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

Откуда: Latvija
Сообщений: 145
declare @aparel int, @special int
set @aparel = 1
set @special = 1	
declare @tableTemp TABLE (id int, name nvarchar)
insert into @tableTemp values (1, 'aaa')
insert into @tableTemp values (2, 'bbb')
insert into @tableTemp values (3, 'ccc')
insert into @tableTemp values (4, 'ddd')

select * from @tableTemp where (case when @aparel = 1 then ID = 1 end) 
	or (case when @special = 1 then ID = 2 end)


Вот такой код дает ошибку Incorrect syntax near '='.
Как ее исправить?
10 май 13, 18:10    [14279635]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
так, как-то
Guest
where id =
case 
  when @aparel = 1 then 1
  when @special = 1 then 2
end
10 май 13, 18:14    [14279648]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Naile
Member

Откуда: Latvija
Сообщений: 145
так, как-то,

Мне надо соблюсти именно условие OR.
Т.е. вывести несколько данных...
10 май 13, 18:15    [14279654]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Naile
так, как-то,

Мне надо соблюсти именно условие OR.
Т.е. вывести несколько данных...
select *
from @tableTemp
where @aparel = 1 and ID = 1 or @special = 1 and ID = 2;
10 май 13, 18:21    [14279671]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
select
 *
from
 @tableTemp
where
 id in (select 1 where @aparel = 1 union all select 2 where @special = 1);
10 май 13, 18:22    [14279673]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Naile
Member

Откуда: Latvija
Сообщений: 145
Спасибо
Исправила на
select * from @tableTemp where id = (case	when @aparel = 1 then 1 end)    or  id = (case when @special = 1 then 2 end)

Работает!
10 май 13, 18:23    [14279675]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Naile
Member

Откуда: Latvija
Сообщений: 145
iap,

Спасибо! это гораздо более умное решение, чем наваяла я.
10 май 13, 18:33    [14279698]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
invm
Member

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

Если есть индекс по id, то в варианте от iap он не будет использоваться.
10 май 13, 19:21    [14279845]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Exproment
Member

Откуда:
Сообщений: 416
, удивлен, что в варианте от iap не отрабатывает индекс. Надо освежить память. Я бы вот так сделал:
select	TT.id, TT.name
from	@tableTemp TT
where	@aparel = 1 and TT.ID = 1	
union all
select	TT.id, TT.name
from	@tableTemp TT
where	@special = 1 and TT.ID = 2;

но вариант от invm sql server оценил как самый производительный, т.к. тот выполняет один index seek(с индексом по id конечно).
13 май 13, 09:46    [14285913]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
invm
Naile,

Если есть индекс по id, то в варианте от iap он не будет использоваться.

Будет. Хотя планы слегка разные, но особой разницы нет.
use AdventureWorks2008;
go
declare @aparel int = 1, @special int = 1
set statistics io, time on

select * from Production.WorkOrder 
where @aparel = 1 and ProductID = 757 or @special = 1 and ProductID = 758;

select * from Production.WorkOrder
where ProductID in (select 757 where @aparel = 1 union all select 758 where @special = 1);

set statistics io, time off
13 май 13, 11:36    [14286516]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
SomewhereSomehow
Будет. Хотя планы слегка разные, но особой разницы нет.
Остается только констатировать, что оптимизатор поумнел. И это хорошо.
13 май 13, 11:57    [14286674]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Exproment
Member

Откуда:
Сообщений: 416
SomewhereSomehow, укажите select @@version плз

ибо у меня в случае:
declare @aparel int, @special int
set @aparel = 1
set @special = 1	
declare @tableTemp table (id int primary key, name nvarchar(max))
insert into @tableTemp
select	top(5000)
		N.ID, N'aaa'
from	dbo.Numbers N
 
select	*
from	@tableTemp
where	(@aparel = 1 and ID = 1) 
		or (@special = 1 and ID = 2)

происходит один clustered index scan. Для версии:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4263.0 (X64)   ...   Copyright (c) Microsoft Corporation  Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor) 
13 май 13, 12:10    [14286768]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Exproment,

Считается, что табличная переменная всегда содержит одну строку. Добавьте в вашем примере option(recompile), чтобы оптимизатор увидел число строк, и ему был резон исследовать альтернативы.
13 май 13, 19:41    [14289397]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Евгений_lea
Member

Откуда:
Сообщений: 75
Здравствуйте
подскажите как написать выражение выборке (выбор режима фильтрации)

select * from planning 
	where  (c.gip_id in (select * from temp1) or @cgip = 0) 
		AND (c.customer_id in (select * from temp2) or @ccust = 0)
		AND 
		(case 
			when @mode = 2 then 
				(
                                  (select MIN(w.date_begin) from plan_works w 
					where id_planning = w.planning_id ) < @dtEnd 
					AND
				 (select MAX(w.date_end) from plan_works w 
					where id_planning = w.planning_id) >= @dtBegin)
			when @mode = 4 then
				(
				 (select MAX(w.date_end) from plan_works w 
					where id_planning = w.planning_id) <= @dtEnd 
					AND
				 (select MAX(w.date_end) from plan_works w 
					where id_planning = w.planning_id) >= @dtBegin)
				)
	             end)  = true

я думал как-то так, но true нет такого выражения
Как правильно написать?
15 май 13, 13:32    [14298893]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Glory
Member

Откуда:
Сообщений: 104760
Евгений_lea
Как правильно написать?

А что должно вернуть выражение
select MAX(w.date_end) from plan_works w where id_planning = w.planning_id) <= @dtEnd
AND
select MAX(w.date_end) from plan_works w where id_planning = w.planning_id) >= @dtBegin

???
15 май 13, 13:37    [14298940]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Евгений_lea
Member

Откуда:
Сообщений: 75
true или false
15 май 13, 13:40    [14298962]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Glory
Member

Откуда:
Сообщений: 104760
Евгений_lea
true или false

Максимальное значение от поля типа date(time) у нас теперь "true или false" ??? И давно ?
15 май 13, 13:41    [14298970]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Евгений_lea
Member

Откуда:
Сообщений: 75
нет да это условие
15 май 13, 13:43    [14298981]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
И как это можно SELECTы использовать в логическом операторе AND??
15 май 13, 13:44    [14298995]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Glory
Member

Откуда:
Сообщений: 104760
Евгений_lea
нет да это условие

Да что вы говорите ? После then все еще идут условия сравнения ? И давно такой синтаскис ввели ? И в каком сервере ?
15 май 13, 13:44    [14299002]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
iap
И как это можно SELECTы использовать в логическом операторе AND??
А! Прошу прощения!
Это я на цитату засмотрелся. В оригинале слегка не так.
15 май 13, 13:45    [14299005]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Евгений_lea
Member

Откуда:
Сообщений: 75
Суть такая, мне нужно чтобы от режима выборки (@mode) список формировался по конечной дате или попадает ли в интервал дат
15 май 13, 13:48    [14299026]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Евгений_lea
Member

Откуда:
Сообщений: 75
ms sql2008
15 май 13, 13:49    [14299032]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Glory
Member

Откуда:
Сообщений: 104760
Евгений_lea
Суть такая, мне нужно чтобы от режима выборки (@mode) список формировался по конечной дате или попадает ли в интервал дат


https://www.sql.ru/forum/127456/rekomendacii-po-oformleniu-soobshheniy-v-forume п.4 и п.6
15 май 13, 13:49    [14299035]     Ответить | Цитировать Сообщить модератору
 Re: CASE в WHERE  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Евгений_lea,

В SQL Server результат сравнения нельзя использовать в произвольных выражениях, как некое битовое значение. То есть нельзя делать, например, так (как вы, вероятно, привыкли делать для C-подобных языков):
declare @bit bit;
set @bit = (1 > 0);

Сравнение можно использовать только для проверки условий в IF, CASE, WHERE (может, ещё где-то):
declare @bit bit;
set @bit = case when 1 > 0 then 'true' else 'false' end;
-- либо
if 1> 0 @bit = 'true' else @bit = 'false';
15 май 13, 13:50    [14299044]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить