Оператор CASE с оператором IN в предложении WHERE - PullRequest
2 голосов
/ 04 ноября 2010

Я пытаюсь создать следующее предложение WHERE:

AND CASE @SomePRarmeter
WHEN 'this' THEN
  user_id IN (SELECT * FROM dbo.func_Id1(@User))
WHEN 'that' THEN
  user_id IN (SELECT user_id from dbo.func_Ids2(@OrgsForReporter)
END

Но я получаю сообщение об ошибке: Неверный синтаксис рядом с ключевым словом «IN» (в первом условии), хотя по отдельности обаэти условия работают.Как правильно сделать такое заявление?

Спасибо!

Ответы [ 5 ]

11 голосов
/ 04 ноября 2010

Попробуйте

AND (
  (@SomePRarmeter = 'this' AND user_id IN (SELECT * FROM dbo.func_Id1(@User)))
  OR
  (@SomePRarmeter = 'that' AND user_id IN user_id IN (SELECT user_id from dbo.func_Ids2(@OrgsForReporter)))
)
2 голосов
/ 04 ноября 2010

Вы делаете выбор * в подзапросе. Вам нужно вернуть только один столбец:

(SELECT * FROM dbo.func_Id1(@User))

к этому:

(SELECT YOUR_USER_ID_COLUMN FROM dbo.func_Id1(@User))
1 голос
/ 04 ноября 2010

Оператор case должен приводить к значению, а не к выражению.Так что это не сработает:

select case when 1=1 then 1 in (1,2,3) end

Но это сработает;

select case when 1=1 then 1 end

Значение может быть результатом подзапроса.Таким образом, одним из решений было бы переписать предложение where, например:

CASE @SomePRarmeter
WHEN 'this' THEN
  (SELECT count() FROM dbo.func_Id1(@User) f where f.user_id = t.user_id))
WHEN 'that' THEN
  (SELECT count() from dbo.func_Ids2(@OrgsForReporter) f where f.user_id = t.user_id))
END > 1

Теперь он возвращает количество совпадающих строк.Затем вы можете фильтровать с помощью case ... end > 1.

0 голосов
/ 04 ноября 2010

CASE ... END возвращает выражение, а не фрагмент буквального кода SQL. Вместо:

AND CASE foo WHEN bar THEN bla=ble END -- Wrong

... вы должны использовать это:

AND bla = CASE foo WHEN bar THEN ble END -- Right

В вашем случае вы можете сделать что-то в этой строке:

-- Untested
AND  (
    (@SomePRarmeter='this' AND user_id IN (SELECT * FROM dbo.func_Id1(@User)))
    OR (@SomePRarmeter='that' AND user_id IN (SELECT user_id from bo.func_Ids2(@OrgsForReporter))
)
0 голосов
/ 04 ноября 2010

Я бы сломал это:

IF 'this'
    SELECT 
    ...
    WHERE user_id IN (SELECT * FROM dbo.func_Id1(@User))
ELSE IF 'that'
    SELECT
    ...
    WHERE user_id IN (SELECT user_id from dbo.func_Ids2(@OrgsForReporter)) 
...