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

Откуда:
Сообщений: 257
Добрый день.

Подскажите, пожалуйста, можно ли в условие WHERE написать CASE
[src]
SELECT .......
where
.................
and CASE
WHEN a.Name = @SYSName THEN not like @SYSName
END
[\src]
при попытки добавить данный кусок кода возникает ошибка

Msg 4145, Level 15, State 1, Procedure payments_GetClientExternalAccounts, Line 82
An expression of non-boolean type specified in a context where a condition is expected, near 'group'.
5 дек 13, 14:58    [15246873]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
user87
Member

Откуда:
Сообщений: 257
Ошибся немного

[src]
SELECT .......
where
.................
and CASE
WHEN a.Name = @SYSName THEN number not like @SYSName
END
[\src]
5 дек 13, 15:03    [15246909]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Glory
Member

Откуда:
Сообщений: 104751
user87
можно ли в условие WHERE написать CASE

можно
user87
при попытки добавить данный кусок кода возникает ошибка

и что должен делать этот кусок ?
5 дек 13, 15:03    [15246911]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
MasterZiv
Member

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

Да, возможно

Но CASE -- это CASE -выражение, а не оператор выбора наподобе IF.

SELECT 1
from sysobjects a
where 1=1
and CASE WHEN a.name = 'XXX' THEN a.Name ELSE null END not like @SYSName


Синтаксис (упрощённо)--

CASE WHEN условие THEN выражение WHEN условие THEN выражение ELSE выражение END
5 дек 13, 15:03    [15246913]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
user87
Member

Откуда:
Сообщений: 257
Спасибо большое
5 дек 13, 15:06    [15246932]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Опять учат людей плохому.
Можно, но не нужно. Никогда.
6 дек 13, 02:01    [15250154]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Mnior
Опять учат людей плохому.
Можно, но не нужно. Никогда.


Что за глупость?
6 дек 13, 02:37    [15250217]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
sdet
Member

Откуда:
Сообщений: 463
MasterZiv
Mnior
Опять учат людей плохому.
Можно, но не нужно. Никогда.


Что за глупость?

На самом деле это не глупость.
Полагаю, что Minor имел в виду, что с таким условием всегда будет table scan и лучше использовать IF вариант для индекса.
6 дек 13, 03:32    [15250262]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
sdet
Member

Откуда:
Сообщений: 463
sdet,

Сорри, опечатался в имени. Правильно Mnior
6 дек 13, 03:35    [15250266]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
sdet
MasterZiv
пропущено...


Что за глупость?

На самом деле это не глупость.
Полагаю, что Minor имел в виду, что с таким условием всегда будет table scan и лучше использовать IF вариант для индекса.


Да мало ли там, может это дополнительное не покрываемое индексами условие или там вообще индекс про выражению есть.
6 дек 13, 12:10    [15251896]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Exproment
Member

Откуда:
Сообщений: 416
MasterZiv, это наверное впервые когда я поддежу Mnior, но строить case-предикаты это реальный бред.
MasterZiv
Да мало ли там, может это дополнительное не покрываемое индексами условие или там вообще индекс про выражению есть.

А вы можете гарантировать, что у вас такого индекса никогда не появится ?
Вы уверены что используя case-предикаты оптимизатор сможет максимально точно определить кардинальность ?
Вам действительно нравится читать case-предикаты ? Взглянув на них вы мгновенно понимаете всю логику которую в них зашили ? Если так, то вы считаете, что case логика более читабельна чем стандартная ?
6 дек 13, 12:48    [15252201]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
baracs
Member

Откуда: Москва
Сообщений: 7217
Exproment
MasterZiv, это наверное впервые когда я поддежу Mnior, но строить case-предикаты это реальный бред.
MasterZiv
Да мало ли там, может это дополнительное не покрываемое индексами условие или там вообще индекс про выражению есть.

А вы можете гарантировать, что у вас такого индекса никогда не появится ?
Вы уверены что используя case-предикаты оптимизатор сможет максимально точно определить кардинальность ?
Вам действительно нравится читать case-предикаты ? Взглянув на них вы мгновенно понимаете всю логику которую в них зашили ? Если так, то вы считаете, что case логика более читабельна чем стандартная ?
Вопрос был "можно или нельзя".
Нравится / не нарвится - отдельная тема.
6 дек 13, 13:10    [15252428]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Exproment
Member

Откуда:
Сообщений: 416
baracs
Нравится / не нарвится - отдельная тема.

это была реакция на:

MasterZiv
Mnior
Опять учат людей плохому.
Можно, но не нужно. Никогда.


Что за глупость?

Если человек решил назвать чужие мысли глупостью, то как минимум он это должен аргументировать. И дело тут не в нравится/не нравится, а в правильно/не правильно. Для меня это больная тема. Работал с системой, где в каждом 10-ом запросе стоял case в предикатах и мне приходилось этот говнокод и его проблемы разгребать. Топикстартер же из темы должен для себя решить точно ли ему стоит использовать case. А темы вроде "вопрос-ответ" не для этого форума, а для "otvet.mail.ru/".
6 дек 13, 13:20    [15252541]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
baracs
Member

Откуда: Москва
Сообщений: 7217
Exproment
baracs
Нравится / не нарвится - отдельная тема.

это была реакция на:

MasterZiv
Mnior
Опять учат людей плохому.
Можно, но не нужно. Никогда.



Что за глупость?

Если человек решил назвать чужие мысли глупостью, то как минимум он это должен аргументировать. И дело тут не в нравится/не нравится, а в правильно/не правильно. Для меня это больная тема. Работал с системой, где в каждом 10-ом запросе стоял case в предикатах и мне приходилось этот говнокод и его проблемы разгребать. Топикстартер же из темы должен для себя решить точно ли ему стоит использовать case. А темы вроде "вопрос-ответ" не для этого форума, а для "otvet.mail.ru/".
"Никогда" - это глупость.
Если вам эта конструкция сильно досадила, это не значит, что она никому никогда не поможет.
И придумывать, что и кому должен ТС, тоже не стоит.
6 дек 13, 13:30    [15252640]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
wizli
Member

Откуда: Minsk
Сообщений: 270
baracs
Exproment
пропущено...

это была реакция на:

пропущено...

Если человек решил назвать чужие мысли глупостью, то как минимум он это должен аргументировать. И дело тут не в нравится/не нравится, а в правильно/не правильно. Для меня это больная тема. Работал с системой, где в каждом 10-ом запросе стоял case в предикатах и мне приходилось этот говнокод и его проблемы разгребать. Топикстартер же из темы должен для себя решить точно ли ему стоит использовать case. А темы вроде "вопрос-ответ" не для этого форума, а для "otvet.mail.ru/".
"Никогда" - это глупость.
Если вам эта конструкция сильно досадила, это не значит, что она никому никогда не поможет.
И придумывать, что и кому должен ТС, тоже не стоит.


Согласен, Mnior погорячился с фразой "никогда". Наверное есть задачи, где эта конструкция может быть использована в качестве решения, хотя, если честно, мне сложно представить такого рода задачи.
Но и повсеместно использовать эту конструкцию в предикатах, довольно таки плохая практика, потому что, как было сказано выше, еще не понятно, как оптимизатор ее обработает. Большинство задач можно решить и без этой конструкции.
А топикстартеру никто не указывает, что и как нужно делать, просто советуют, чтобы он точно определил для себя, стоит ли использовать эту конструкцию в своем решение или нет, в силу причин указанных выше. Просто могут возникнуть проблемы с производительностью(index seek не будет) или оптимизатор может ошибся в оценке кардинальности из-за этой конструкции, а это может повлечь за собой очень серьезные проблемы.
6 дек 13, 13:43    [15252782]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Вообще говоря, CASE - это синтаксическая конструкция,
жёстко гарантирующая порядок проверки условий WHEN.
Иногда это просто необходимо.
Операторы же в WHERE оптимизатор может выполнять в
том порядке, который сочтёт нужным.

Так что иногда CASE в WHERE совершенно необходим.
6 дек 13, 13:45    [15252814]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
Вообще говоря, CASE - это синтаксическая конструкция,
жёстко гарантирующая порядок проверки условий WHEN.
Иногда это просто необходимо.
Операторы же в WHERE оптимизатор может выполнять в
том порядке, который сочтёт нужным.

Так что иногда CASE в WHERE совершенно необходим.

Predicate ordering is not guaranteed
6 дек 13, 13:58    [15252925]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

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

CASE свободно преобразуется в обычное условие, пусть даже OR - даже там иногда скуль сможет оптимизнуть.
А выражения типа @Var = <Const> сможет убрать или сделать "Startup Filter" в плане, фактически опустив запрос целиком или ветку запроса частично.

Но если там есть колонки - то скуль не сможет CASE оптимизнуть, ибо он не линеен и можно сказать недетерминирован.

Если CASE "закрыт", не использует ничего из самого запроса и может быть заменён на переменную, то и обычное выражение без CASE скуль догадается свернуть в преобразование (ну может быть вырожденные случаи, но это редкость).

Обычное выражение (AND OR) читается проще - не обрамлено CASE WHEN THEN ELSE END мусором.
6 дек 13, 16:22    [15254347]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

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

Засада в другом, доказательства строятся в основном от противного. Т.е. опровергнуть чаще намного проще, приведя пример, а вот чтобы доказать - нужно порой приводить сложные умозаключения. И продолжение засады в том, что если собеседник не привык к такой сложности его тяжело "убедить".
Особенно это касается гуманитариев. Экставертов, рационалов.

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

wizli
Наверное есть задачи, где эта конструкция может быть использована в качестве решения
"Может быть" не значит что "всё, надо CASE выбирать"
- обычное выражение проще выглядит и
- не понадобится переписывать CASE, как только формула усложнится и оптимизация накроется медным тазом.

Я, как ещё часто просматривающий чужой код, всегда переписываю выражения, и по возможности выставляю его.
Ибо все недоказанные до конца (формально) предположения висят домокловым мечём и жаждят найти опровержение.
6 дек 13, 16:44    [15254538]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Mnior
Если CASE "закрыт", не использует ничего из самого запроса и может быть заменён на переменную ...
То очень вероятно что где-то недоработка. Скорее всего этот CASE - это некоторое понятие, которое надо "заименовать".
Функцией или колонкой в представлении, т.е. вынести за пределы это кода или даже скуля вообще.
Ибо "закрытость" есть звоночек нарушение границы - а независимость кода, есть практически обязанность современного программирования, чтобы вмещать большую сложность проектов, их надёжность и гибкость. А также готовой возможности повторного использования.

Кому-то это очевидно. Если говорить об иррационалах и интровертах.
И понятно что наличие такого подхода к программированию сразу даёт определённые требования к формату и структуре кода.
И появляются множество таких "никогда так не писать" или "стараться так не писать".

Думаю, ошибку между 0 и 0.000001 можно всё-таки не называть глупостью. Замазав это эмоциональным посылом, чтобы заглушить намного большую разницу между 0.3 и 0.000001. Не так ли?
6 дек 13, 17:02    [15254718]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
OlM
Guest
Mnior
Обычное выражение (AND OR) читается проще - не обрамлено CASE WHEN THEN ELSE END мусором.

Mnior, я согласен с тем, что (AND OR) читается легче. Но из моей практики, в сложных запросах конструкция
WHERE	T1.ID = CASE WHEN @idItem1 = 0 THEN T1.ID ELSE @idItem1 END
AND	T2.ID = CASE WHEN @idItem2 = 0 THEN T2.ID ELSE @idItem2 END 

предпочтительнее, чем
WHERE	( T1.ID = @idItem1 OR @idItem1 = 0 )
AND	( T2.ID = @idItem2 OR @idItem2 = 0 )

В подавляющем большинстве случаев планы выполнения идентичные, но... не всегда. И если они не идентичны, то второй вариант проигрывает с разгромной разницей. Я не готов сейчас выложить пример, но если Вы этого захотите - организую в течение следующей недели.
6 дек 13, 22:30    [15256133]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
iap
Вообще говоря, CASE - это синтаксическая конструкция,
жёстко гарантирующая порядок проверки условий WHEN.
Иногда это просто необходимо.
Операторы же в WHERE оптимизатор может выполнять в
том порядке, который сочтёт нужным.

Так что иногда CASE в WHERE совершенно необходим.
iap, вы предлагаете направление поиска опровергающего примера?
Или он у вас есть?

Что-то сложное/тяжёлое это только подзапрос (или вызов внешней невразумительной хрени). Загромождать им CASE - ещё хуже запутать. Не надо ограничиваться только операторами в WHERE. Сложный подзапрос можно обрамить нормально во FROM с нормальной связкой прописав запрос-отсечение.

И тут вы предлагаете вариант с ошибкой в расчётах плана, на кривой статистике к примеру или багах оптимизатора.
И поэтому:
1. вы не сможете привести пример, это тяжело/муторно подобрать
2. ещё тяжелее доказать рациональность написания CASE, вместо того же положенного и адекватного обновления статистики, или упрощения запроса.
3. И показать, что человеку при кривом плане на руках очевиднейше придёт в голову попробывать именно CASE.
OlM
WHERE	T1.ID = CASE WHEN @idItem1 = 0 THEN T1.ID ELSE @idItem1 END
AND	T2.ID = CASE WHEN @idItem2 = 0 THEN T2.ID ELSE @idItem2 END 
предпочтительнее, чем
WHERE	( T1.ID = @idItem1 OR @idItem1 = 0 )
AND	( T2.ID = @idItem2 OR @idItem2 = 0 )
второй вариант проигрывает с разгромной разницей. Я не готов сейчас выложить пример, но если Вы этого захотите - организую в течение следующей недели.
С нетерпением жду.

У iap хотя бы направление вразумительное есть. Хотя вы примерно одинаково думаете, вы предлагаете вариант где выражение одинаково не оптимизируется в принципе, но хотите поймать выкрутас, где можно сыграть в другое, совершенно не связанное с самим запросом.

Смотрите, если оно не связано - значит "закрытое" и не относится к WHERE, и свободно выносится "за скобки", оставляя только значение.
Если оно связано, то оптимизатор выворачивает это в "Full Scan" палюбэ. А значит можно свободно перенести в SELECTивную часть и связать/отфильтровать снаружи.
7 дек 13, 04:33    [15257025]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Mnior,

я ж ссылку дал. И много тем тут было, в которых некто хочет выбрать из таблицы
только записи со строковым полем, преобразуемым к другому типу (обычно числовому).
А оптимизатор сначала всё равно пытается вычислить выражение, хотя, казалось бы,
написано "сначала проверь, что поле преобразуется в число".
Сервер не смотрит на порядок условий, а выполняет их в удобном ему порядке.
Но в CASE он не имеет право так делать.
Я не спорю, возможно само возникновение такой ситуации говорит об ошибке в проектировании...
Зачем, например, данные разного типа хранить в одном поле?

OlM,

а ничего, что Ваши варианты WHERE приводят к разным результатам?
Первый никогда не пропустит T1.ID IS NULL, например
7 дек 13, 12:09    [15257374]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
iap,

Да, да, есть такое, с 2005го появилось.
Но как я писал - выносится из WHERE зоны. Часто в представление или в APPLY.

OIM,

В вашем примере от ситуации планы выворачиваются на изнанку. Т.е. вернуть дофига строк или одну.
В таких случаях пишут несколько запросов для каждого случая объединяя в UNION ALL.
7 дек 13, 16:41    [15258176]     Ответить | Цитировать Сообщить модератору
 Re: Возможно ли вписать CASE в условие WHERE  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Exproment
baracs
Нравится / не нарвится - отдельная тема.

это была реакция на:

MasterZiv
пропущено...


Что за глупость?

Если человек решил назвать чужие мысли глупостью, то как минимум он это должен аргументировать. И дело тут не в нравится/не нравится, а в правильно/не правильно. Для меня это больная тема. Работал с системой, где в каждом 10-ом запросе стоял case в предикатах и мне приходилось этот говнокод и его проблемы разгребать. Топикстартер же из темы должен для себя решить точно ли ему стоит использовать case. А темы вроде "вопрос-ответ" не для этого форумам, а для "otvet.mail.ru/".


Аргументы я привел. Ещё раз, есть много вариантов использования case в where, когда производительность запроса страдать не будет. Да и в конце концов, это проблема ТС и совсем другая тема.

Я написал "глупость" чтобы у людей не создавалось ложного впечатления, что case в where писать нельзя.
7 дек 13, 17:21    [15258311]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить