Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4 5   вперед  Ctrl      все
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Exproment
Member

Откуда:
Сообщений: 416
MasterZiv
Ещё раз, есть много вариантов использования case в where, когда производительность запроса страдать не будет

мне еще раз написать про кардинальность и прочее ?
MasterZiv
производительность запроса страдать не будет

производительность - это единственный критерий качественного написания кода ? + "не страдает" != "улучшает"
MasterZiv
чтобы у людей не создавалось ложного впечатления, что case в where писать нельзя.

Дык в том-то и дело, что нельзя и это должно быть правилом! Но естественно у всего есть исключения и если очень долго искать, то когда-нить можно найти ситуацию, где case будет предоставлять некоторую выгоду в решении(сам не видел, но в теории допускаю). Но это как с GUID'ом, он уникален, но тем не менее повторится может. Но никто не будет в работе учитывать данную вероятность.

case упорядочивает сравнение предикатов - если вы начали руками их упорядочивать, то у вас явно что-то не так.
пример с конвертацией типов - ну тут архитектура. На основе плохой архитектуры всегда будет плохой код, это не показывает "полезность" case'а.
7 дек 13, 18:41    [15258544]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Exproment,

"Дык в том-то и дело, что нельзя и это должно быть правилом! "

Нет такого правила "нельзя". Есть другое правило: "Думай".
7 дек 13, 20:32    [15258790]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Exproment,

case упорядочивает сравнение предикатов - если вы начали руками их упорядочивать, то у вас явно что-то не так.

Это кто это их упорядочивал?
7 дек 13, 20:34    [15258792]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
+
MasterZiv
Я написал "глупость" чтобы у людей не создавалось ложного впечатления, что case в where писать нельзя.
Чушь всё это, нет такого случая. Ничего они не потеряют если будут даже не писать по незнанию.

MasterZiv, не надо делать из себя героя-освободителя на пустом месте.
Нет аргументов что стоит писать, нету их. Я всё расписал подробно и разжёванно - но ни на один аргумент вы не отетили вы просто, тупо повторяете о каких-то там "ложных впечатлений".
Это называет наглой ложью.

MasterZiv
"Дык в том-то и дело, что нельзя и это должно быть правилом! "
Нет такого правила "нельзя". Есть другое правило: "Думай".
Как много информации вы привели, прям раздавили тяжестью.
Что "думай"? Конкретно!

Вы можете чуть более точно формализовать? Не можете. Не можете формализовывать мысли? Только "думай", "думай не знаю как"?
Плять, что бы учить кого-то нужно уметь формализовывать это "думай", и показывать.
А в итоге пустозвонство.

"Будь хоть Эйнштейном в квадрате, но пока ты нем и не можешь ничего выразить, прока с тебя не больше чем от макаки".

Повторяю, CASE-у нет места в WHERE.
Все преобразования и формулы находятся в SELECT или APPLY расширениях, включая выкусывания данных их строк, требующих порядок условий, т.е. CASE. Все чистые и полные связки находятся во FROM, все чистые условия фильтрации в WHERE. И не стоит смешивать это:
Преобразования и связки не переносить в другие части (WHERE), или наоборот. Слава богу запретили такие операторы как *=, =* и *=* (хотя всё равно умудряются связки там писать)
Если придерживаться этих правил, то код будет чистым и понятным и не приводить к "магическим" результатам по невнимательности.

+
Отклонения от правил уже на вашей совести, но для других, кто может увидеть ваш код, а код часто кто-то повторно будет смотреть (если конечно вы его сразу не отправляется в /dev/null) это будет выглядеть как езда зигзагами на магистрали, если не хуже, в зависимости от степени свинства.
А у свиней всё просто, всё "правильно" пока не понимаешь другую сторону, ну зачем тратить время выслушивать чужие аргументы.

PS: Громко сказано, некоторые увидят только эмоции:
Какие мерзкими словами он выражается, так выражаются только плохие дяди, ай-яй-яй. В газовую камеру паразита.
Шутка.
8 дек 13, 00:31    [15259400]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
baracs
Member

Откуда: Москва
Сообщений: 7217
Exproment
пример с конвертацией типов - ну тут архитектура. На основе плохой архитектуры всегда будет плохой код, это не показывает "полезность" case'а.
Вы меня улыбаете.
Много вы видели реальных, работающих систем с безупречной структурой БД?
Развивается бизнес, развивается система - меняется структура БД и, чаще всего, не в лучшую сторону.
Так что, для тех кто имел дело с БД с историей, полезность case-а не требует строгих доказательств.
8 дек 13, 20:42    [15261387]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Exproment
Member

Откуда:
Сообщений: 416
baracs
Так что, для тех кто имел дело с БД с историей, полезность case-а не требует строгих доказательств.

1,5 года работал с БД в несколько терабайт с историей около 10 лет. Не написал не одного case-предиката. Переписал десятки чужих case-предикатов. Сферическая БД в вакууме конечно сказки, но уж поправить архитектуру вам видимо мешает бизнес ? Любят многие ныть про "это невозможно исправить", "логика упадет" и т.д. На деле же это должна быть просто эпическая говносистема, чтобы нельзя было решить такие мелкие проблемы. Пример "быстрого" решения конвертации типов - вычисляемые столбцы.
MasterZiv
Это кто это их упорядочивал?

ну кто-то выше приводил данную опцию как полезность case'а)
8 дек 13, 21:15    [15261476]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
baracs
Member

Откуда: Москва
Сообщений: 7217
Exproment
...но уж поправить архитектуру вам видимо мешает бизнес ?
IT-руководитель: "Будет заявка на оптимизацию, будем думать.". И он по-своему прав.

Есть конторы, где без специальной заявки индекс нельзя перестроить (добавить include колонку). А вы говорите: "Поправить архитектуру".
Лихой казак.
9 дек 13, 12:36    [15263861]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
iap
а ничего, что Ваши варианты WHERE приводят к разным результатам?
Первый никогда не пропустит T1.ID IS NULL, например

Вы правы, вообще говоря - это не тождественные варианты. Но, как Вы можете видеть, я применяю их там, где NULL невозможен, так что в моем частном случае функциональность у вариантов идентичная.
Mnior
В вашем примере от ситуации планы выворачиваются на изнанку. Т.е. вернуть дофига строк или одну.
В таких случаях пишут несколько запросов для каждого случая объединяя в UNION ALL.

В принципе - да, UNOIN может быть лучше. А вот в частности - нет, не может. Каждое такое условие удваивает количество сегментов UNION. В примере, который я взял из боевого запроса не менее боевого отчета, таких условий 6. Писать UNION из 64 сегментов? За что же Вы меня так не любите?

Теперь пример:
+
DECLARE	@FDate		datetime
,	@TDate		datetime
,	@ClientID	int
,	@FundID		int
,	@LegalEntityID	int
,	@ClassID	int
,	@InvestorID	int
,	@Internal_External	int


-------- Version 1

SELECT THST.ID

--  Много чего убрано...

FROM		tblHistory		AS	THST	with (nolock)
 
INNER JOIN	tblSeries		AS	TSRS	with (nolock)	ON	TSRS.ID	= THST.SeriesID 
 
INNER JOIN	tblClass		AS	TCLS	with (nolock)	ON	TCLS.ID	= THST.ClassID  
INNER JOIN	tblLegalEntity		AS	TLNT	with (nolock)	ON	TLNT.ID	= TCLS.legalentityid  
INNER JOIN	tblFund			AS	TFND	with (nolock)	ON	TFND.ID	= TLNT.FundID 
INNER JOIN	tblClient		AS	TCLN	with (nolock)	ON	TCLN.ID	= TFND.ClientID 

INNER JOIN	trelClassInvestor	AS	TRCI	with (nolock)	ON	THST.ClassID  = TRCI.ClassID  
									AND	THST.InvestorID  = TRCI.InvestorID 

INNER JOIN	dbo.ft_Returns_BASIC	(	@ClientID	 
					,	@FundID		
 					,	@LegalEntityID		
					,	@ClassID	
					)	AS	 RETS		ON	RETS.ID	= THST.ID


WHERE 	THST.ValDate BETWEEN @FDate AND @TDate 
AND	TCLS.Deleted = 0 
AND	TLNT.Deleted = 0  
AND	TFND.Deleted = 0
AND	TCLN.Deleted = 0

AND	TFND.ClientID	= CASE WHEN (ISNULL (@ClientID, 0)	= 0) THEN TFND.ClientID		ELSE @ClientID		END  
AND	TFND.ID		= CASE WHEN (ISNULL (@FundID, 0)	= 0) THEN TFND.ID		ELSE @FundID		END  
AND	TLNT.ID		= CASE WHEN (ISNULL (@LegalEntityID, 0)	= 0) THEN TLNT.ID		ELSE @LegalEntityID	END 
AND	THST.ClassID	= CASE WHEN (ISNULL (@ClassID, 0)	= 0) THEN THST.ClassID		ELSE @ClassID		END 
AND	THST.InvestorID	= CASE WHEN (ISNULL (@InvestorID, 0)	= 0) THEN THST.InvestorID	ELSE @InvestorID	END 
AND	TRCI.InternalExternalID	= CASE WHEN (ISNULL(@Internal_External,0) NOT IN (1,2))	THEN TRCI.InternalExternalID ELSE @Internal_External END



-------- Version 2

SELECT THST.ID

--  Много чего убрано...

FROM		tblHistory		AS	THST	with (nolock)
 
INNER JOIN	tblSeries		AS	TSRS	with (nolock)	ON	TSRS.ID	= THST.SeriesID 
 
INNER JOIN	tblClass		AS	TCLS	with (nolock)	ON	TCLS.ID	= THST.ClassID  
INNER JOIN	tblLegalEntity		AS	TLNT	with (nolock)	ON	TLNT.ID	= TCLS.legalentityid  
INNER JOIN	tblFund			AS	TFND	with (nolock)	ON	TFND.ID	= TLNT.FundID 
INNER JOIN	tblClient		AS	TCLN	with (nolock)	ON	TCLN.ID	= TFND.ClientID 

INNER JOIN	trelClassInvestor	AS	TRCI	with (nolock)	ON	THST.ClassID  = TRCI.ClassID  
									AND	THST.InvestorID  = TRCI.InvestorID 

INNER JOIN	dbo.ft_Returns_BASIC	(	@ClientID	 
					,	@FundID		
 					,	@LegalEntityID		
					,	@ClassID	
					)	AS	 RETS		ON	RETS.ID	= THST.ID


WHERE 	THST.ValDate BETWEEN @FDate AND @TDate
AND	TCLS.Deleted = 0 
AND	TLNT.Deleted = 0 
AND	TFND.Deleted = 0
AND	TCLN.Deleted = 0

AND	( TFND.ClientID		= @ClientID		OR	ISNULL (@ClientID, 0)		= 0 )
AND	( TFND.ID		= @FundID		OR	ISNULL (@FundID, 0)		= 0 )
AND	( TLNT.ID		= @LegalEntityID	OR	ISNULL (@LegalEntityID, 0)	= 0 )
AND	( THST.ClassID		= @ClassID		OR	ISNULL (@ClassID, 0)		= 0 )
AND	( THST.InvestorID	= @InvestorID		OR	ISNULL (@InvestorID, 0)		= 0 )
AND	( TRCI.InternalExternalID = @Internal_External	OR	(ISNULL(@Internal_External,0) NOT IN (1,2)) )

Планы выполнения - прилагаются. Скажете - кривая статистика? Вполне может быть. Но если есть два варианта, которые одинаково хорошо работают на хорошей статистике и по-разному на плохой, какой из них выбрать? "Идеологически правильный" или более производительный?

Т.е. на практике этот трюк позволил мне в разы повысить быстродействие отчетов даже на плохой статистике. Я что-то сделал неправильно?

К сообщению приложен файл (Plans.zip - 14Kb) cкачать
9 дек 13, 21:33    [15267320]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM
Каждое такое условие удваивает количество сегментов UNION.
Не каждое. Т.е. может быть такое - но в целом это редкость. Давайте не спускаться до коня в вакууме.
Если запросы сложные - то используют динамический подход. Recompile. И я не совсем уверен, что всякий CASE сможет с оптимизироваться (хотя такие простые щёлкает).
OlM
В примере, который я взял из боевого запроса не менее боевого отчета, таких условий 6. Писать UNION из 64 сегментов?
Нет конечно. Надо решить задачу, подумать головой. Массовые вещи пустить в заранее описанные оптимальные случаи, редкие - применить другие подходы.

Только это большая редкость, даже для этого (сложные или массовые запросы) права разные раздают и в одном запросе не смешиваются. А смешивать до кучи - непонимание и халатность.

OlM
Скажете - кривая статистика?
Да подозреваю что тут всё кривое.
1. Прилагаемые планы кривые:
Object reference not set to an instance of an object. (SqlMgmt)
at Microsoft.SqlServer.Management.SqlMgmt.ShowPlan.ObjectWrapperTypeConverter.Convert(SeekPredicatesType item)
В них отсутствуют секции <SeekPredicates />
2. Кривой запрос, пишите схемы в именах, не создавайте условий для отложенной компиляции.
3. Кривой запрос, ваши условия во втором запросе не симметричны. Чистый "или" не пересекается. Правильно писать так:
+
DECLARE	@FDate			DateTime
,	@TDate			DateTime
,	@ClientID		Int
,	@FundID			Int
,	@LegalEntityID		Int
,	@ClassID		Int
,	@InvestorID		Int
,	@Internal_External	Int

SELECT	THST.ID
,	...
FROM	dbo.tblHistory			AS	THST
JOIN	dbo.tblSeries			AS	TSRS	ON	TSRS.ID	= THST.SeriesID
JOIN	dbo.tblClass			AS	TCLS	ON	TCLS.ID	= THST.ClassID
JOIN	dbo.tblLegalEntity		AS	TLNT	ON	TLNT.ID	= TCLS.legalentityid
JOIN	dbo.tblFund			AS	TFND	ON	TFND.ID	= TLNT.FundID
JOIN	dbo.tblClient			AS	TCLN	ON	TCLN.ID	= TFND.ClientID
JOIN	dbo.trelClassInvestor		AS	TRCI	ON	THST.ClassID	= TRCI.ClassID
							AND	THST.InvestorID	= TRCI.InvestorID
JOIN	dbo.ft_Returns_BASIC	(	@ClientID
				,	@FundID
 				,	@LegalEntityID
				,	@ClassID
				)	AS	 RETS	ON	RETS.ID	= THST.ID

WHERE 	THST.ValDate		>= @FDate
AND	THST.ValDate		<  @TDate 
AND	TCLS.Deleted		= 0
AND	TLNT.Deleted		= 0
AND	TFND.Deleted		= 0
AND	TCLN.Deleted		= 0
-- V1
AND	TFND.ClientID		= CASE WHEN @ClientID		IS NOT NULL THEN @ClientID		ELSE TFND.ClientID		END
AND	TFND.ID			= CASE WHEN @FundID		IS NOT NULL THEN @FundID		ELSE TFND.ID			END
AND	TLNT.ID			= CASE WHEN @LegalEntityID	IS NOT NULL THEN @LegalEntityID		ELSE TLNT.ID			END
AND	THST.ClassID		= CASE WHEN @ClassID		IS NOT NULL THEN @ClassID		ELSE THST.ClassID		END
AND	THST.InvestorID		= CASE WHEN @InvestorID		IS NOT NULL THEN @InvestorID		ELSE THST.InvestorID		END
AND	TRCI.InternalExternalID = CASE WHEN @Internal_External	IN (1,2)    THEN @Internal_External	ELSE TRCI.InternalExternalID	END
-- V2
AND (	TFND.ClientID		= @ClientID		 OR @ClientID		IS NULL)
AND (	TFND.ID			= @FundID		 OR @FundID		IS NULL)
AND (	TLNT.ID			= @LegalEntityID	 OR @LegalEntityID	IS NULL)
AND (	THST.ClassID		= @ClassID		 OR @ClassID		IS NULL)
AND (	THST.InvestorID		= @InvestorID		 OR @InvestorID		IS NULL)
AND (	TRCI.InternalExternalID	= @Internal_External	AND @Internal_External	    IN (1,2)
 OR	@Internal_External	IS NULL			 OR @Internal_External	NOT IN (1,2))	-- Тут можно и перефразировать
А параметры нужно или правильно подавать, или приводить.
4. NoLock и другие вещи (подозреваю отсутствие индексов судя по планам, да банальный BETWEEN) намекают на всё остальное.
OlM
Вполне может быть. Но если есть два варианта, которые одинаково хорошо работают на хорошей статистике и по-разному на плохой, какой из них выбрать? "Идеологически правильный" или более производительный?
Причём тут идеологический правильный и "производительный". Вы смешиваете понятия "запутывание сервера" и "оптимизация".
В вашем случае скуль теряется и случайным образом делает линейный план который вас устраивает в данный момент времени. Идеологически правильно, если вас что-то не устраивало или планы не стабильны, нужно пользоваться соответствующими хинтами.
Можно подставить что угодно, любые не детерминированные функции в данном запросе, чтобы сбить. Но CASE в данном случае конкретно не причём, и использовать его тут не нужно.

А ещё, подставьте Recompile к моему варианту и покажите план.
OlM
Т.е. на практике этот трюк позволил мне в разы повысить быстродействие отчетов даже на плохой статистике. Я что-то сделал неправильно?
Почти всё неправильно.
Хотите вам тут прооптимизируют этот запрос до нормального состояния?

Это когда-нибудь кончится. Я хочу говорить с адекватными людьми.
Чтобы у вас не валилось, даю исправленные планы:

К сообщению приложен файл (Plans.x.zip - 15Kb) cкачать
10 дек 13, 01:42    [15268103]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Конечно хочу, я никогда не отказываюсь от возможности подучиться.
10 дек 13, 02:11    [15268133]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Знаете, я посидел немножко над Вашим вариантом... Вы заметили, что сами себя опровергли? Вы, фактически, объединили варианты 1 и 2. Результат впечатляющий, не спорю, и завтра я буду внимательно и вдумчиво его изучать. Но как этот результат согласуется с Вашим утверждением:
Mnior
Повторяю, CASE-у нет места в WHERE

Все, на этом на сегодня заканчиваю, продолжим завтра, если не возражаете.
10 дек 13, 02:43    [15268156]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM
Вы заметили, что сами себя опровергли?
Где?
OlM
Вы, фактически, объединили варианты 1 и 2.
Ничего не объединял, там два варианта, я просто не дублировал общие части.
10 дек 13, 11:27    [15269533]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Вот как? Забавно. Потому что именно сводный вариант дает интересные результаты. Но давайте по порядку. Сначала – по Вашим пунктам.

1. Хм... Проблема нестыковок версий? План строится 2008 сервером, а работаю я в студии 2005 (привычнее). Ну, следующие планы сохраню из-под 2008 студии.

2. Согласен, косяк. Не мой, правда, но я его прохлопал ушами. Ну и в данном конкретном случае на скорость он, все-таки, не влияет.

3. Возражаю. Ваши изменения неверны, потому что любой из параметров (кроме дат) может принимать значения как NULL, так и 0, что с точки зрения бизнес-логики одно и то же. Просто во втором случае юзверь выбрал опцию «Все клиенты» (0), а в первом даже не озаботился выбрать хоть какую-то из опций (NULL). Все комментарии по поводу разумности такого подхода – в пользу бедных, потому что UI давно написан и редизайну в обозримом будущем не подлежит. Так что Ваш вариант вернет неправильный набор данных.
На всякий случай обращаю Ваше внимание, что поскольку в выражениях типа ISNULL ( @idClient, 0 ) = 0 табличные данные никак не участвуют, то и вычисляются эти выражения только один раз. Хотя (тут я согласен с Вами) - это плохой стиль. Но... опять же - на скорость, в данном случае, не влияет. Или я неправ?

4. По четвертому пункту -сразу несколько вопросов. Если не секрет – чем Вам не нравится NoLock и как это сказывается на быстродействии и планах?
Что касается BETWEEN – оптимизаторы умнеют версия от версии. Раньше я тоже избегал BETWEEN, но с 2008 перестал. Планы-то – одинаковые. Или я неправ?
Если не секрет, в каких местах Вы ожидали увидеть индексы, но не увидели их? Это не сарказм - у меня вполне мог замылиться глаз. Но пока что я не вижу, какой еще индекс мог бы помочь.

Ну и что же у нас остается от тюнинга запроса? Только исправление некритичной небрежности со схемами. Я ожидал большего. А самое главное, я так и не увидел почему CASE – это плохо, и как без него обойтись, не занимаясь навязыванием сиквелу своих версий планов.

Кстати, о планах. Все операции с ними, а также ковыряния со сводным вариантом - после сна, когда приду на работу. Все, я - спать.
10 дек 13, 13:27    [15270781]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM
1. Хм... Проблема нестыковок версий? План строится 2008 сервером, а работаю я в студии 2005 (привычнее). Ну, следующие планы сохраню из-под 2008 студии.
Это косяк к MS.
Вы разрешаете выложить ваши планы на connect.microsoft.com ?
OlM
3. Возражаю. любой из параметров может принимать значения как NULL, так и 0, что с точки зрения бизнес-логики одно и то же.
Ну не бизнес логики, в предметной области голые понятия, а так вы запрогали, но я вам сразу же ответил:
Mnior
А параметры нужно или правильно подавать, или приводить.
Пусть с клиента приходят данные как хотят, нужно их однозначно и удобно для скуля преобразовать. Но лучше на клиентской части.
NULL для того и ввели - что это означает неопределённые данные.
OlM
«Все клиенты» (0)
Неважно как оно обзывается - в смыслах он "неопределённый".
И поэтому NULL = <Что Угодно> по умолчанию "не истина". В итоге выражения логически симметричны.
OlM
потому что UI давно написан и редизайну в обозримом будущем не подлежит.
UI тут не причём.
Входные параметры можно и желательно "терминировать":
SELECT	@ClientID	= NullIf(@ClientID	,0)
,	@FundID		= NullIf(@FundID	,0)
,	@LegalEntityID	= NullIf(@LegalEntityID	,0)
,	@ClassID	= NullIf(@ClassID	,0)
,	@InvestorID	= NullIf(@InvestorID	,0)
А желательно, т.к. обходится "особенность" скуля компилировать процедуры на основании значений параметров первого запуска.
OlM
Так что Ваш вариант вернет неправильный набор данных.
Поэтому он вернёт правильные данные.
Это же не логическая ошибка, а ошибка интерфейса вызова. Из-за бардака в вашем проекте.
OlM
ISNULL ( @idClient, 0 ) = 0 вычисляются эти выражения только один раз.
Повторяю, логическое выражение у вас не симметрично. Ибо в природе существует комбинация удовлетворяющая обоим условиям:
[Column] = @Param OR IsNull(@Param,0) = 0 -- Если [Column] = 0
А так как выражения компилируются до запроса и совершенно независимы от данных, то выражения не дополняющие, а пересекающиеся. А это совершенно другие логические свойства.
OlM
Но... опять же - на скорость, в данном случае, не влияет. Или я неправ?
Скорость это не свойства выражений. Надо смотреть на оптимальный план, на возможность генерации оптимальных планов оптимизатором.
OlM
чем Вам не нравится NoLock и как это сказывается на быстродействии и планах?
Это может сказываться на "чистоте" данных. И NoLock, имхо, признак плохой системы и плохого разработчика.
Если вы, предположим как "эксперт", будете говорить что это экономия на установке-снятии локировок, то тогда у вас был бы идеальный запрос, идеальный план, идеальная структура, что-бы дойти до таких экономий на спичках, и всё равно до такого редко спускаются.
OlM
Что касается BETWEEN – оптимизаторы умнеют версия от версии. Раньше я тоже избегал BETWEEN, но с 2008 перестал. Планы-то – одинаковые. Или я неправ?
Тут дело не в оптимизации, BETWEEN не делает проблем как таковой и всегда разворачивает в два выражения. Синтаксический сахар. Но:
1. Не стоит этот сахар его употребления. А логика "ни хуже, значит будем вносить зоопарк" не стоит того.
2. Но главное другое, это запись ">= AND <=", а если вы заметили я написал ">= AND <". Ибо время есть непрерывная величина. (уже устаю это разжёвывать). А бесконечную прямую можно разрезать только двумя равномерными способавми, или "выколотая точка" справа или слева. Т.к. начало считает обычно от нуля, то поэтому "справа".
Равенство с обоих сторон означает что строка (с "нулевым" временем) может попасть в оба периода идущих друг за другом. Что есть ошибка.
OlM
в каких местах Вы ожидали увидеть индексы, но не увидели их?
Сознаю что анализировал поверхностно, но вроде как нет необходимых индексов по связкам (FK).
OlM
у меня вполне мог замылиться глаз. Но пока что я не вижу, какой еще индекс мог бы помочь.
Ссори, будет время может посмотрю, но когда нет условий (структура/схема) это делается на порядок медленее.
OlM
Я ожидал большего.
А что вы ожидали? У вас была цель решить свою проблему, а не найти внятное "опровержение, что CASE не нужен"?!
OlM
А самое главное, я так и не увидел почему CASE – это плохо
Кто ищет, тот всегда найдёт.
Тяжело в таком режиме навязывать точку зрения - несподручно. Но дело в том что это дело каждого хотеть докопаться. Ведь не в противостояние же мы тут играем:
- Ты не смог доказать, что 2+2=5, значит я прав, 2+2=3.
OlM
и как без него обойтись, не занимаясь навязыванием сиквелу своих версий планов.
При общем правильном построении системы и общем правильном написании запросов - планы автоматически делаются верными.
Есть конечно исключения и баги, но это мелочи.
А ещё, хинты сами по себе не зло, не каждые, они так же носят описательный характер.
Вы Recompile попробывали?
10 дек 13, 19:49    [15273642]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Извините, задержался с ответом – я ушел в небольшой отпуск, а последний перед отпуском день был просто сумасшедшим.

Итак, по пунктам.

1. Честно говоря, не хотелось бы - в нашей конторе весьма параноидальные порядки. Я и на этом сайте с большой оглядкой пасусь, благо "хранители секретов" ни бельмеса по-русски.

3. Знаете, а ведь я поначалу Вас просто не понял. Более того, я никогда и не задумывался о симметричности условий, а это серьезное упущение. Спасибо. Значит я уже не напрасно влез в разговор.

4. NoLock
Mnior
признак плохой системы и плохого разработчика

Ха! ))))) Хотите я Вам еще с десяток таких признаков накидаю? Как Вам, например, асболютно случайные, ни на секунлу не sequential GUID’ы с кластерными primary индексами поверх них? А поверх этого еще и аудит на основе CDC, что само по себе доставляет, но ко всему еще и делает невозможным ребилд такого индекса без остановки аудита? Плюс необходимость получения полудюжины подписей для такой остановки? А как Вам XML поля, где они даром не нужны? Да еще и реализованые так, что их и не проиндексируешь? А как Вам внешняя аппликуха, которая апдейтит семь таблиц в одной транзакции, причем ну АБСОЛЮТНО без каких-нибудь реальных показаний для такой бешеной транзакции? А как вам табличная функция, которая "на лету" калькулирует то, что должно быть скалькулировано один раз и храниться в той же упомянутой в примере таблице tblHistory (кстати, странно, что Вы эту функцию не упомянули – а ведь колоссальный ресурс для оптимизации. Вы ведь заметили, что джойнится она по ID?) Эту функцию сделали как временную заплатку, но осталась она на годы, а техзадание на ее убийство все еще не утверждено. А Вы говорите – NoLock... ))))))) К сожалению, в наших условиях NoLock реально помогает выживать. Благо грязное чтение в данных отчетах на практике исключено. Совершенно не сиквеловскими методами, но тем не менее.

BETWEEN
Ах вон Вы о чем... ))) Я-то думал – это наследие тяжких времен )))
Ну а если серьезно, то Ваше исправление ">= AND <" я заметил, но посчитал опечаткой и не стал придираться к мелочам. Но раз это не опечатка, то отвечаю. Если бы в нашей системе время рассматривалось как непрерывная величина, то да, тогда Вы были бы правы. Но у нас в системе время квантуется по дням. Т.е. в данном поле в принципе нет дат с "ненулевым" временем. Так же, как и в аргументах @FDate и @TDate. И нам нужны именно ">= AND <=" данные.
А утверждение
Mnior
Не стоит этот сахар его употребления

все-таки требует аргументации.

Mnior
А что вы ожидали? У вас была цель решить свою проблему, а не найти внятное "опровержение, что CASE не нужен"?!

Да, вообще-то, у меня нет проблем с этим запросом. У проекта в целом – да, есть проблемы, но не я их создал, не я и решу, если вообще кто-то когда-то их решит. Просто после слов "все не так" и "а давайте мы вам все прооптимизируем" невольно возникли ожидания получить мастер класс по оптимизации. Не вполне оправданые. Хотя и не совсем обманутые, см. тот же п. 3.

А появился я здесь, чтобы озвучить и обсудить пример, когда применение CASE привело к улучшению плана. Как я понимаю, сама логика фильтрации в моем запросе действительно запутывает оптимизатор, и в этом главная трудность.

Как Вы правильно сказали, эту трудность можно разрешать
а) динамическим запросом
б) через UNION (точнее, пожалуй, через INSERT во временную таблицу с ветвлением по IF'ам)
в) хинтованием
г) ухищрениями с запросом, в надежде что оптимизатор "случайно" выберет хороший план.

Так вот меня больше всего интересует последний случай. Дело в том, что оптимизатор не так-то уж и случайно строит план. Если в запросе оставить только одну таблицу и к ней применять эти дурацкие фильтры "все или ничего", планы будут идентичными, какой из вариантов фильтрации не примени. Идентичными во всем, кроме ожидания количества возвращаемых записей. И эта разница в ожиданиях выстреливает, когда надо джойнить отфильтрованные таким образом результаты.

В связи с этим мне интересно – знак этой разницы в ожиданиях стабилен, а следовательно зависит от выбранного синтаксиса, или нестабилен, а следовательно зависит от данных? Если первое, то применением или неприменением CASE'а можно косвенно управлять построением плана.
12 дек 13, 13:17    [15282156]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM
К сожалению, в наших условиях NoLock реально помогает выживать.
Мне часто больше везло, что хватало времени и реакции чтобы не довести или исправить ситуацию.
Но всё равно не я настаиваю на том что NoLock чаще (практически всегда) можно опустить когда его встречают в коде.
Есть такое подход, когда что-то трогаешь, не оставляй это плохо сделанным. Т.е. исправь этот участок, ну и соседний проверь (но не дальше) - таким образом система исправляется, потихоньку. Желательно ещё иметь чуйку накапливаемости архитектурных/структурных проблем, что бы знать куда приложить больше усилий и контроля.

OlM
Mnior
(уже устаю это разжёвывать)
Если бы в нашей системе время рассматривалось как непрерывная величина
Время непрерывно с любой точки зрени. Ок, согласен, "пространственная величина" будет более точное определение. Не важно, можно ли его квантовать или нет. Я советую перечитать ту ссылку (спойлер "Обисняю как трёхлетнему").
Со временем ещё важно то, что на нём определено несколько дискретизаций, что усугубляет степень вашей ошибки.
2. Поэтому есть только диапазоны.
3. При обозначении одной величины (2012-05-16 21:10:34) понятно что она является границей двух диапазонов
4. Поэтому для исключение перекрытия (дублирования) принято что эта точка принадлежит одному диапазону (не принадлежит другому)
7. DateTime (точность 1/3 секунды), SmallDateTime(точность 1/3 минуты), Date (точность день)

Совершенно не важно, в каких точных типах вы описываете время, всё равно вы описываете момент времени. Вы не можете указать полдень или вечер в типе Date. Только полночь, начало новых суток.

Когда пишут <= '2012-02-29', видно что выражение сильно зависит от выбранной системы мер. Если будет день с концом, то одно, если время, то другое.
Но когда пишут < '2012-03-01' совершенно неважна точность и система мер. Можно смело заменить Date на DateTime в такой системе и всё всё равно будет работать как надо.
Основная ошибка в логике рассуждений, её ещё называют "Бритва Оккама", это:
1. Минимальность правил, при покрытии большего числа случаев.
2. Минимальность зависимостей и параметров.
Подгонка "работает на практике, в частном случае" под "значит верно" и "остальное неважно" плохая гуманитарная практика.
Для меня как технаря/логика критически важно общность и минимальность правил/законов.
Ибо большое число зависимостей и следовательно их проффтыкание приводит к логическим ошибкам. Учёт зависимостей - значит сознательный их подсчёт - значит стремление их минимизировать - значит стремление выбрать минимальные правила. В обратном случае, по обратной цепочке (нет минимальности правил - нет стремления к подсчёту зависимостей - нет их учёта - много логических ошибок) определяет принцип мышления и приоритет "навешивания ярлыков" этого человека (что некоторые гуманитарии любят делать). Суховато сказал, но надеюсь посыл был понят.

Дополню:
Получается что одно и та же величина имеет два разных значения:
2013-12-13 >= означает на начало дня, и та же величина
<= 2013-12-13 означает на конец дня

Мне для определения диапазонов, нужны только границы-моменты, а вам нужно определять начало и конец - две величины, каждый раз высчитывать эти величины (следующий месяц минус день, к примеру).
У меня одно значение на границе ('2012-03-01') где есть до и после, а у вас появляется финдеперсовая ('2012-02-29') и что тогда висит между "концом предыдущего месяца" ('2012-02-29') и "началом следующего" ('2012-03-01')?! А ничего не может быть - ибо это одно и тоже, но у вас это "одно и тоже" выражается по разному.

OlM
невольно возникли ожидания получить мастер класс по оптимизации
:) Ну вы конечно, чуть что так сразу. Да я и не смотрел особо, а другие тоже.
Почему я сказал что индексов не хватает - потому что во втором плане есть MERGE JOIN, перед которым идёт сортировка.
Для начала надо было показать реальный план запроса, а не предположительный - заодно посмотрим как сильно ошибается статистика.
Если статистика не актуальна из-за того что данные берутся по "новым данным", тогда ставится хинт:
OPTION (OPTIMIZE FOR (@FDate = '<DateFrom>', @TDate = '<DateTo>'))
Где выбираются оптимальные значения констант (<DateFrom>, <DateTo>, где-то задним днём, главное что бы там данные были постоянно). И аналогичто по другим параметрам (указывается NULL). И тем самым закрепляется план.
14 дек 13, 12:38    [15292426]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Mnior
Основная ошибка в логике рассуждений, её ещё называют "Бритва Оккама", это нарушение правил:
1. Минимальность правил, при покрытии большего числа случаев.
2. Минимальность зависимостей и параметров.
*fix
14 дек 13, 12:44    [15292444]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Если не возражаете, я сегодня отвечу в расслабленно-философском стиле, без конкретики в виде планов и прочего. В конце концов - я в отпуске, и сегодня открыл горнолыжный сезон ну и бутылочку вина по этому поводу ))

Так вот, бритва Оккама - великолепный принцип познания мира. Познания. Но этот принцип не применим к инструментарию созидания.

Да, можно построить дом работая одним топором. Но это не означает, что долото и рубанок не имеют право на существование, хотя по упомянутому принципу - это лишние сущности, умножения которых следовало бы избегать. Да, можно программировать в машинных кодах. Сигнальные процессоры, вроде бы, до сих пор так и программируют (хотя могу и соврать). Но разве это лишает права на существование языки высокого уровня? Да, можно обойтись исключительно конструкциями ">=AND<". Но разве это означает, что BETWEEN не имеет права на существование? Конечно нет.

Я понимаю все, что Вы утверждаете по отношению "пространственным величинам". Понимаю и принимаю.

Но! Согласитесь и Вы, что любая "пространственна величина" может быть конвертирована в множество дискретных, штучных сущностей. Да, конвертирована с потерей точности, ну и что? Например, высота здания легко конвертируется в его этажность. И поверьте мне, коменданту гостиницы глубоко плевать, что канделябр, стоящий на столе, находится выше ковра, лежащего на полу. Единственное, что его интересует, так это то, что оба предмета находятся на одном и том же этаже. Согласитесь, что в "этажном варианте" инструкции: "красить в красный цвет - с первого этажа включая и по шестой этаж исключая, а в зеленый - с шестого этажа включая и по одинадцатый исключая" будут выгладеть по меньшей мере странно. Особенно если в здании только десять этажей.

Точно так же любой отрезок времени легко конвертируется в набор дней. И если по условию задачи имеет значение не @SomeDate, а именно CONVERT(datetime,CONVERT(varchar,@SomeDate,1),1) (способ конвертации взят напрямую из здешнего FAQ'а), то это означает, что бухгалтерам совершенно безразлично, во сколько часов минут и секунд произошла транзакция. Их волнует только день. И все, что Вы абсолютно справедливо написали по поводу непрерывных "пространственных величин", перестает быть применимым - еще раз, как только мы позаботились о конвертации.

Между прочим, в английском языке это даже лингвистически отслеживается. Когда мы говорим о времени, как о "пространственной величине", вопрос "Сколько времени вам нужно?" звучит как "How much time do you need?" Однако стоит нам только перейти к дискретным сущностям - дням, как все сразу меняется! И вопрос "Сколько дней нужно чтобы... ?" звучит как "How many days will it take to...?"
15 дек 13, 11:31    [15294785]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
+ OlM
OlM
Если не возражаете, я сегодня отвечу в расслабленно-философском стиле ...
Возражаю!
Ваши "рассуждения" по принципу аналогий яркий пример как размышлять нельзя. Аналогией можно преподносить информацию, человека несведущего, чтобы принял, хоть и не понял. "Рассуждения" такого плана это наркоманский бред,
OlM
Я понимаю все, что Вы утверждаете по отношению "пространственным величинам".
Судя по всему нет.
OlM
Понимаю и принимаю.
Что-то не видно.

Ок. поговорим вашим языком.
Вы имеете на руках топор, молоток и микроскоп. И вам дали конкретную задачу, забить гвозди. Не шурупы, не нарубить дров, или потрошить лягушку. И вы говорите
- Ок, микроскопом можно забивать, конечно иногда неудобно, но сегодня можно.
- Ну в принципе молотком легче (по причинам: а,б,с, .. x,y,z.), хотя тут можно и микроскопом. Отвечают вам.
- Подождите, микроскопом правильно, с философской точки зрения. А молоток это инсинуации. Возражаете вы.
FacePalm.JPG
автор
Но разве это означает, что BETWEEN не имеет права на существование?
Т.е. из слов что для времени BETWEEN не удобен из-за ряда причин, вы делаете вывод что я категорически запрещаю его использовать?!
OlM
Да, можно построить дом работая одним топором. Но это не означает, что долото и рубанок не имеют право на существование, хотя по упомянутому принципу - это лишние сущности, умножения которых следовало бы избегать. Да, можно программировать в машинных кодах.
Вам чётко показали что использовать ">= и <" проще в любом ракурсе, как понимать так и поддерживать, но в ответ - "BETWEEN! Палюбэ!". А я что могу вас заставить? Зачем так отбрыкиваться? Словно вас держат за причинное место.
OlM
Но разве это лишает права на существование языки высокого уровня?
Мда ... ИМХО, вы совершенно не понимаете что такое языки высокого уровня и что такое декларативное программирование.
OlM
much, many
Вы не можете отделить качественные величины от количественных?
If you can count it and it doesn't designate a category, use many.
If you cannot count it or it designates a category, use much.
Да, да, как в BETWEEN так и в программировании вообще качественные величины в основном и указываются. Угу.

OlM
Так вот, бритва Оккама - великолепный принцип познания мира. Познания. Но этот принцип не применим к инструментарию созидания.
В мемориз.
"Инструментарию созидания"! бл?*:!. "Созидания" - ипать.
"Созидание нахуячивания". Простите меня за мой французский.
Вы конечно правы, мистер Френки!

PS: Это была такая шутка?
PPS: Не, пора сваливать с этой планеты.
16 дек 13, 20:53    [15301421]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Весь гневный пафос Вашего последнего поста зиждется на ложной посылке:
Mnior
Вам чётко показали что использовать ">= и <" проще в любом ракурсе
.
Так вот, НЕ ПОКАЗАЛИ. Для моего частного случая - не показали. Продекларировать не значит доказать. А если Вы и вправду собираетесь доказывать это для "любого ракурса"... флаг Вам в руки.
автор
Вы не можете отделить качественные величины от количественных?

Я-то как раз могу. И пытаюсь объяснить разницу Вам. Вы говорите - о времени. Я говорю - о днях (сутках). Вы видите разницу между абстрактным отрезком времени и набором дней? Если нет, я не вижу смысла продолжать наш разговор.
Mnior
Вы имеете на руках топор, молоток и микроскоп. И вам дали конкретную задачу, забить гвозди. Не шурупы, не нарубить дров, или потрошить лягушку. И вы говорите
- Ок, микроскопом можно забивать, конечно иногда неудобно, но сегодня можно.
- Ну в принципе молотком легче (по причинам: а,б,с, .. x,y,z.), хотя тут можно и микроскопом. Отвечают вам.
- Подождите, микроскопом правильно, с философской точки зрения. А молоток это инсинуации. Возражаете вы.

Вы будете смеяться, но меня у сложилось впечатление, что именно Вы предлагаете микроскоп вместо молотка. Т.е. с точностью до знака.
Mnior
Да, да, как в BETWEEN так и в программировании вообще качественные величины в основном и указываются. Угу.

Это Вы самого себя цитируете?
Mnior
"Рассуждения" такого плана это наркоманский бред...

Знаете, голуба, надоели Вы мне. Идите на улицу, постойте на морозе и остыньте. А не хотите на улицу - просто идите, идите, идите...
17 дек 13, 00:32    [15302217]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM, вы меня простите, но вашей глупостью и слепотой вы просто напрочь отбиваете всякое желание.
Поэтому прошу простить меня за долгий ответ.

OlM
Так вот, НЕ ПОКАЗАЛИ. Для моего частного случая - не показали.
1. раздражённо вам заявляю - не "не показали", а "OlM не захотел вкрадчиво прочитать и долго обдумать сказанное".
2. Тут же написали ошибку непонимания. Я показал неизменность подхода для любого частного случая.
Но это фразу вы не поймете. Даже облившись ледяной водой. Как не поймёте и то что:
Это нельзя доказать тотальным превосходством одного подхода перед другим только в частном порядке.
Но так как вы видите одинаковость в обоих подходах в частном случае - ваш гуманитарный ум делает ошибку - из одинаковости выводит превосходство "родного" подхода.
Видя результат этого мышления - меня воротит.
OlM
Продекларировать не значит доказать.
Вы понимаете что вы пишете?
А дошло ... кто сильный тот и прав. Гуманитарии, сэр.
OlM
А если Вы и вправду собираетесь доказывать это для "любого ракурса"... флаг Вам в руки.
Мне просто противно писать очевидные банальности, но видимо придётся:

Мне нужно использовать только одну вещь независимо от частностей случая. Всегда писать ">= AND <". Всё!!!
1. Есть время (миллисекунды) или их нету? Неважно - ">= AND <" работает всегда, BETWEEN не работает для всех случаев.
2. Нужно рассчитывать конечную дату? Неважно, у ">= AND <" всегда совпадают время начала и конца. BETWEEN такое не умеет - иногда надо ипаться с расчётом кочечной даты, с ">= AND <" не нужно никогда.

Нет, всётаки писать примеры для этих двух тезисов - это даже не ясельки для младенцев, скорее для даунов.
OlM
И пытаюсь объяснить разницу Вам.
Вы? Мне? Объяснить? Вы лукавите!
OlM
Вы говорите - о времени. Я говорю - о днях (сутках).
Да, я говорю о времени. Не о секундах, а о абстрактном времени. О годах (где нет месяцев), о месяцах (где нет дней), о днях (где нет часов), о миллисекундах, которые могут быть как 000 так и 789. В общем бл?*:! смысле, для каждого случая отдельно и при этом одновременно (в подходе).
В русском языке нет слова которое говорит о времени вообще и никак о секундах. (Мне ничего не приходит на ум)
И какого хрена вы из этих двух понятий в одном синониме выбираете только одно ("выгодное" для тупого спора). В моих словах за меня выбираете что я имел ввиду?!
+ Совет для OlM
Если вы видите что собеседник ошибся. Значит 100% ВЫ ошиблись в его понимании. Перед тем как написать что он неправ, остановитесь. Поверьте что вы 100% ошиблись, ибо это так. И начните думать где вы ошиблись и перебирайте варианты
+ и лулзы для остальных
Эти гуманитарии думают, что технари не придерживаются этого совета, что это чисто язвительно написано для них. Эмоции сэр.
Даже подсмотрев это, они всё равно предполагают что технари иногда не придерживаются этого совета. Природная наивность, сэр.

OlM
Вы видите разницу между абстрактным отрезком времени и набором дней?
Набора дней здесь нет! Вы не используете запрос "= 5 дней", у вас нет DateDiff. Мы говорим об интервалах. Определёнными двумя величинами.
OlM
Если нет, я не вижу смысла продолжать наш разговор.
Ваша проблема в том что вы не слушаете, вы хотите что бы вам доказали вашим подходом и вашей тактикой в вашем направлении.
Мне же приходится как показывать ошибки вашего подхода, так и попытаться развернуть ваше видение, что бы вы сами всё увидели.
OlM
Вы будете смеяться, но меня у сложилось впечатление, что именно Вы предлагаете микроскоп вместо молотка. Т.е. с точностью до знака.
Ок. Аналогия вещь, как я писал говно - каждый видит свою часть слона.
Повторюсь, секунды тут не причём. Я не о них говорил.
Не верите? Перепрочитайте мой пост и убедитесь.
+
OlM
Это Вы самого себя цитируете?
Ага, сарказма там не было. Да, да.
OlM
Знаете, голуба, надоели Вы мне. Идите на улицу, постойте на морозе и остыньте. А не хотите на улицу - просто идите, идите, идите...
Привет гуманитариям. Чуть есть эмоции так сразу нах... Какие же вы "миленькие ду....

OlM, мне уже глубого пофег если вы это не поймёте. Вы можете 100500 раз умолять что я "неправ" - но это будет бесполезно.
Есть какая-то чаша терпения. Ссори.

PS: Модёрам. Перед тем как удалять, оставьте хоть те два тезиса. Хотя я и не знаю когда для вас "перешли грань" или нет.
И попытайтесь хоть сами вразумить человеку, если вы так критично относитесь к сказанному.
23 дек 13, 02:04    [15331628]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Вы все-таки вернулись с мороза? )) Ну, воля Ваша, продолжим веселить публику.

Опуская эпитеты, которые гораздо больше говорят о Вас, чем обо мне, сосредоточусь на содержательной части. Во-первых, Mnior, Вы или крайне небрежны в формулировках и деталях, или потихоньку начинаете подменять предмет спора. В последнем посте Вы пишете:
Mnior
Я показал неизменность подхода для любого частного случая.

Да, такой подход возможно использовать в любом случае. Но речь-то шла не о том. Напомню Вашими же словами из более раннего поста:
Mnior
Вам чётко показали что использовать ">= и <" проще в любом ракурсе

Mnior
...степень вашей ошибки

Mnior, Вы вообще знаете разницу между словами "возможно" и "проще"? И между понятиями "неправильно", "правильно", "единственно правильно"? Или забываете о чем вообще речь? Так я напомню. Все начиналось с Ваших утверждений, что применение BETWEEN - это ошибка, поскольку:
Mnior
А бесконечную прямую можно разрезать только двумя равномерными способавми, или "выколотая точка" справа или слева. Т.к. начало считает обычно от нуля, то поэтому "справа".
Равенство с обоих сторон означает что строка (с "нулевым" временем) может попасть в оба периода идущих друг за другом. Что есть ошибка.

Я попытался объяснить Вам, что в конкретном случае нашей системы мы в принципе не работаем с "временной" составляющей даты, мы ее отбрасываем еще перед занесением данных в базу. Я не стал этого озвучивать, полагая, что Вы поймете самостоятельно, что после такой конвертации дат, варианты
WHERE ValDate >= '20130101' AND ValDate < '20130201'
WHERE ValDate >= '20130101' AND ValDate <= '20130131'

полностью, т.е. абсолютно эквивалентны, потому что такая конвертация автоматически учитывает "выколотую точку". Но я был слишком оптимистичен, Вы этого не поняли:
Mnior
Время непрерывно с любой точки зрени. Ок, согласен, "пространственная величина" будет более точное определение. Не важно, можно ли его квантовать или нет. Я советую перечитать ту ссылку (спойлер "Обисняю как трёхлетнему").
Со временем ещё важно то, что на нём определено несколько дискретизаций, что усугубляет степень вашей ошибки.

Так вот - нет никакой ошибки. Еще раз: НЕТ НИКАКОЙ ОШИБКИ. Считаете иначе? Нет проблем! Все нужные формулы (в том числе и для конвертации) здесь были нарисованы. Пример данных на которых эти формулы не работают - в студию! Или отзывайте ваши громкие заявления об ошибке.

Ну а то, что наш подход нам ПРОЩЕ и УДОБНЕЕ Вашего - это просто объективная реальность. Попытайтесь самостоятельно понять - почему. Не поймете - спросите, я охотно объясню. Впрочем, есть еще одна опция - можно продолжать жить в параллельной вселенной в окружении сферических коней. Это на Ваш выбор.

Собственно, на этом можно было бы и закончить, но все-таки сделаю еще несколько замечаний.
Mnior
BETWEEN не работает для всех случаев

Ошибка. Правильно: "BETWEEN работает не для всех случаев". (Технарь, говорите? Ну-ну.)
Mnior
Эти гуманитарии думают...

Ошибка. У меня высшее техническое образование. Два диплома, оба советского образца (это на случай, если соберетесь фантазировать еще и по поводу моего возраста).
Mnior
OlM, вы меня простите, но вашей глупостью и слепотой вы...

Ошибка. Переход на личности - всегда ошибка.
Mnior
Поэтому прошу простить меня...

Единственный шаг в правильном направлении. К сожалению, скорее всего, следующих шагов Вы не сделаете, а это - очередная ошибка. Тем не менее - прощаю.
23 дек 13, 21:37    [15336359]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM
Вы или крайне небрежны в формулировках и деталях, или потихоньку начинаете подменять предмет спора.
Значит вы согласились что недопоняли. И до вас начинает потихоньку доходить. Замечательно.
Т.е. вы перешли ту грань что "Mnior неправ", в то что может "выражается непонятно для вас".
OlM
Да, такой подход возможно использовать в любом случае.
Отлично, значит с основным тезисом (15273642), что не стоит заморачиваться с BETWEEN вы согласились.
Что нет ни одного аргумента, что BETWEEN необходим, на котором вы ранее настаивали. Отлично.
OlM
Напомню Вашими же словами из более раннего поста:
Mnior
Вам чётко показали что использовать ">= и <" проще в любом ракурсе
А что не так? Да, в частном ракурсе он может не хуже, но в целом он лучше. Или вы настаиваете на интерпретации "для каждого ракурса по отдельности он лучше", при этом вы обяжите игнорировать все те тезисы которые говорят об обратном? Это смешно и нелепо.
Вот вам фраза для поиска:
Mnior
1. Не стоит этот сахар его употребления. А логика "ни хуже, значит будем вносить зоопарк" не стоит того.
Заметьте, сказано раньше всех остальных тезисов.
OlM
Все начиналось с Ваших утверждений, что применение BETWEEN - это ошибка, поскольку:
Нет, дорогой мой. Выкручиваться бесполезно. Строить что я тотально неправ, и вся правда на вашей стороне из подхода подмены смысла - не прокатит.
Не вы определяете смысл мною сказанного, а я, пытавшись формализовать мысль словами. Не путайте причину и следствие. И если что-то можно проинтерпретировать многозначно, то вы не можете отбросить эту многозначность и сказать "вы имели ввиду только это, и только", это деструктивный разговор.

Мы можем апеллировать только и только к ошибкам неточности сказанного и однозначно взаимоисключающих параграфов.

Я перечислял многогранность явления, с разных ракурсов, и вы не можете взять вырвать эту грань и пристроить к другой и сказать "Поэтому вы неправы". Что вы ниже и пытаетесь делать.

OlM
Mnior
А бесконечную прямую...
Я попытался объяснить Вам, что в конкретном случае нашей системы мы в принципе не работаем с "временной" составляющей даты, мы ее отбрасываем еще перед занесением данных в базу.
Вы всё также не понимаете бесполезность этого аргумента, и из этого делаете вывод что я его типа не понял. Очередной раз.
При этом сколько я говорю о бесполезности этого аргумента - и вы опять своё непонимание ставите как доказательство. Бред.

1. Я пишу и рассматриваю случай А (бесконечной прямой в общем смысле, не в каждом - а в общем, бл?*:!). А вы апеллируя к нему о случае Б (частный случай).
Как можно апеллировать несвязанным аргументом? Это бред.

Если вы хотите рассмотреть отдельный случай, так зачем вы апеллируете к общему?
Как в анекдоте "а вот блохи". Причём тут блохи?!

2. Если вы настаиваете на частном случае - то я вам писал, что доказать превосходство в каждом, частном случае я даже не собирался.
Но при этом дополнительно показывал глупость этого подхода:

1. Этот аргумент не доказывает преимущества BETWEEN. Уже можно забить на остальное.
2. Для любой системы дискретизации можно найти такие пары чисел (дофига пар) при котором будут пересечения (или недосечения). Когда уровни дискретизации не совпадают.
А существование пар при котором не будет этого - ничто не доказывает!
3. Стратегия необходимости подсчёта таких пар что нет пересечений - неудобна и излишняя.
4. Подход убивает гибкость кода. И привязывается к конкретным дискретам.
Выполнение этого требования неудобно и не всегда возможно.

OlM
Я не стал этого озвучивать, полагая, что Вы поймете самостоятельно
бл?*:!, понимание этого тезиса было подтверждено ещё до того как вы начали его приводить:
Mnior
А логика "ни хуже, значит будем вносить зоопарк" не стоит того.
Это что можно как-то по другому интерпретировать? Т.е. я это сказал, но при этом этого не понимаю?
Будте внимательны.
Если вы не можете собрать воедино все эти элементы одновременно - поздравляю, логика вам недоступна.
OlM
т.е. абсолютно эквивалентны
Нет! Абсолютно эквивалентные значит при любых частных случаях. А тут они частно эквивалентны.
OlM
потому что такая конвертация автоматически учитывает "выколотую точку"
Она не учитывает выколотую точку, ибо это вещь определена только для непрерывных или обобщённых величин.
OlM
Так вот - нет никакой ошибки. Еще раз: НЕТ НИКАКОЙ ОШИБКИ.
Проблема что вы не правы не в том, что я якобы утверждаю что ваш способ даёт якобы всегда ошибки, это вы себе надумали. Вы всегда хотите свести всё только к двум вариантам:
Или а) что-то всегда лучше для всех случаев
Или б) что-то всегда хуже для всех случаев
Третьего не дано. - Это бред!

Если можно написать что-то через BETWEEN - это не значит что он имеет право на существования при оптимальном подходе в программировании. Оно должно давать хоть какое-то преимущество.
А оно даёт кучу проблем при смене чего либа, или при очепятках может дать скрытые большие проблемы.
ФТОПКУ.

OlM
Ну а то, что наш подход нам ПРОЩЕ и УДОБНЕЕ Вашего - это просто объективная реальность.
Потому что гладиолус? Объективаная реальность - которую невозможно выразить словами, и при этом всегда получается что-то наоборот.
Т.е. то что надо дополнительно считать некий "конец периода" это типа преимущество. Считать по разному для каждого дискретного случая? Это удобство?
Т.е. при ошибке несоответствия дискретности данных и кода (они несвязаны явно) это выливается в неправильные данные (пересечение) это типа преимущество?
Назовите хотя бы один единственный якобы аргумент (больше вы не сможете назвать принципиально), давайте давайте. Я жду. И даже на нём я покажу недостаток этого подхода.

+
OlM
Попытайтесь самостоятельно понять - почему.
Естественно. Я должен просто признать вашу правоту, ибо вы её никак не можете доказать. Поэтому надо демонстративно "поднять ручки", "сдаться" и сказать в слух что "OlM прав", иначе он заплачет и обидеться. Да? Детсад какой-то.
OlM
Не поймете - спросите, я охотно объясню.
Ну так давайте. попытайтесь выразить словами. Попытайтесь доказать аргументированно.
OlM
можно продолжать жить в параллельной вселенной в окружении сферических коней.
От суть гуманитария - непонятно - значит бред. Гуманитарий идеален по определению, если он что-то не понял, то не важно почему - он прав априори.
OlM
Собственно, на этом можно было бы и закончить, но все-таки сделаю еще несколько замечаний.
Потирает руки от предвкушения.
OlM
Mnior
BETWEEN не работает для всех случаев
Ошибка. Правильно: "BETWEEN работает не для всех случаев". (Технарь, говорите? Ну-ну.)
Попался. Родимый. Проявляется гуманитарная логика.
Если вы это интерпретируете только как "не работает ни для одного случая" - то вы ошиблись. Вы не работали с кванторами всеобщности и существования. Вы не чувствуете разрыв формальной логики и народного языка. Если бы вы на этом заморачивались, вы бы чувствовали хотя бы "так в народе не говорят" и поэтому "двоякость восприятия".
"не для всех случаев" - можно перестановкой вывести в "существует случай не". И заметьте - это никак не эквивалентно "работает не для всех".
Для этого понимания, именно вам рекомендую детскую книжечку от создателя "Алисы в Зазеркалье" - Льюис Кэрролл "Логическая игра". Может поможет.
OlM
Mnior
Эти гуманитарии думают...
Ошибка. У меня высшее техническое образование. Два диплома, оба советского образца (это на случай, если соберетесь фантазировать еще и по поводу моего возраста).
Попадос номер два. Гуманитарий это не профориентация - это тип мышления. Даю вам ключевое слово - Соционика.
Аппеляция к социальному статусу (аж два - бумажка и возраст) это один из ярких проявлений гуманитарства.
У кого длиннее тот и прав.
OlM
Переход на личности - всегда ошибка.
Пападос номер 3. Интерпретировать слова как оскорбление и ничего другого не видеть - ещё одно проявление сенсорика/этика.
Ошибка в чём? Тут сразу проявляются цели. Если ваша цель придти к консенсусу двух личностей, проявлять этическую заботу, перевести на свою сторону барикад - это всё бред и тупость. Наоборот, если такой слоган отпугнёт человека не ставящего истину целью - тем лучше, пусть бежит со всех ног, проблем меньше возится с постоянно ошибающимися в логике гуманитариями.
OlM
Mnior
Поэтому прошу простить меня...
Единственный шаг в правильном направлении.
Попадос номер 4. Чуствительность к общественным поглаживаниям (этике) ещё один признак гуманитартсва.
OlM
К сожалению, скорее всего, следующих шагов Вы не сделаете
Вы имеете ввиду что признать что вы правы без аппелирования к аргументам, а просто так взять, не мучая вас, пролееять множеством приятных слов? Какой вы хороший и умный человек, а я дурак - так как не вижу очевидности всеобъемлюще правильного подхода BETWEEEN?
Да без проблем, забирайте два.
Если вы так жаждите "ну в чём-то он не прав, в чём-то оно ошибается, а мне это необходимо увидеть", то без проблем могу вам дать ссылки на это.. Хотя и сами можете поискать по ключевым словам.
Может успакоитесь и сосредоточитесь на смысле - только толку ноль, постоянно следить за вашим уровнем беспокойства и постоянным отвлеканием - сизов труд.
24 дек 13, 06:14    [15337179]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior,

Знаете, поначалу я хотел разобрать Ваш ответ по пунктам... Но зачем? Вам это ничего не даст - Вы уже закусили удила. А посторонний читатель и так уже имеет возможность соспоставить наши точки зрения. Так что, давай-те ка на этом и завершим сей увлекательнейший диалог. С наступающими Вас!
24 дек 13, 06:44    [15337201]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
OlM
Все нужные формулы (в том числе и для конвертации) здесь были нарисованы. Пример данных на которых эти формулы не работают - в студию!
Где? Где тут формулы?
Где формулы расчёта даты окончания периода?

Напишите мне одно общую формулу даты окончания периода для:
1. Годовой дискретизации (есть только указание года)
2. Квартальной дискретизации
3. Месячной дискретизации
4. Недельной,
...
N. С точностью DateTime
M. С неизвестной точностью

Покажите мне сохранность формулы и всех запросов, когда руководство решило делать отчёты не по дневному, а по 3х часовому интервалу данные уже с увеличенной точность.

Покажите переносимость принципов построение запросов при смене проекта.
А теперь стоимость переписывания.

А теперь покажите недостатки в подходе с ">= AND <".

А теперь используя только BETWEEN определите, что два периода пересекаются или не пересекаются.

У меня есть табличка dbo.Movеments, с полем типа DateTime. Что мне в моей таблице надо поставить в BETWEEN для отбора данных за этот месяц?

Покажите мне ваш запрос за один день. А теперь скажите каковы последствия попадание строки со временем в вашем случае.

Имеется две даты периода в вашем случае. Покажите формулу расчёта длины этого периода на основе этих дат.
А если дискретизация неделя. и т.д. общая формула для всех дискретизаций.

Попытайтесь написать запрос через BETWEEN с точностью DateTime, который бы всегда правильно работал.

Почему в Excel (и не только) существует 1900-02-29 ?
А если дата будет приходить извне, а не рассчитываться в скуле?

А если вдруг старая версия клиента, которая не учитывает что теперь даты со временем?
24 дек 13, 06:55    [15337206]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4 5   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить