Как использовать оператор CASE внутри WHERE с предложением IN? - PullRequest
6 голосов
/ 15 мая 2019

Я пытаюсь сделать следующее (псевдокод, поскольку он не компилируется):

declare showListedOrSold  int = 1 -- get value from config table

select *
from table
where CASE WHEN @showListedOrSold = 0 THEN id IN (1, 2, 5, 6, 10, 11) 
             WHEN @showListedOrSold = 1 THEN id IN (1, 5, 6, 10, 11) 
             WHEN @showListedOrSold = 2 THEN id IN (2) 
      END

В основном в зависимости от значения showListedOrSold, оно должно вернуть определенные значения id.

Оператору не нравится предложение IN.Каков правильный синтаксис для этого варианта использования?

Ответы [ 6 ]

7 голосов
/ 15 мая 2019

Если вы хотите «элегантное решение», вы можете сохранить эти значения в таблице, которую можно использовать в вашем запросе.

CREATE TABLE #ValidIds(
    ShowListedOrSold int,
    id int);

INSERT INTO #ValidIds
VALUES( 0, 1),
      ( 0, 2),
      ( 0, 5),
      ( 0, 6),
      ( 0, 10),
      ( 0, 11),
      ( 1, 1),
      ( 1, 5),
      ( 1, 6),
      ( 1, 10),
      ( 1, 11),
      ( 2, 2);

SELECT *
FROM table t
JOIN #ValidIds v ON t.id = v.id
AND v.ShowListedOrSold = @ShowListedOrSold;
6 голосов
/ 15 мая 2019

Вы можете решить эту проблему, используя ИЛИ вместо CASE:

SELECT *
FROM table
WHERE (@showListedOrSold = 0 AND id IN (1, 2, 5, 6, 10, 11))
        OR (@showListedOrSold = 1 AND id IN (1, 5, 6, 10, 11))
        OR (@showListedOrSold = 2 AND id IN (2))
5 голосов
/ 15 мая 2019

Это начинает становиться довольно сложным.Я мог бы порекомендовать подход join:

select t.*
from table t join
     (values (0, 1), (0, 2), (0, 5), (0, 6), (0, 10), (0, 11),
             (1, 1), (1, 5), (1, 6), (1, 10), (1, 11),
             (2, 2)
     ) v(slos, id)
     on t.slos = @showListedOrSold and
        v.id = s.id

Вы можете легко развернуть это, чтобы показать все строки, если переменная null:

     on (t.slos = @showListedOrSold and
         v.id = s.id
        ) or
        @showListedOrSold is null
2 голосов
/ 15 мая 2019

как работает кейс, вам нужно будет вернуть значение, а затем проверить его.

declare @showListedOrSold int = 1 -- get value from config table

select  *
from    [table]
where   (case
            when @showListedOrSold = 0 and  id in (1, 2, 5, 6, 10, 11) then 1
            when @showListedOrSold = 1 and  id in (1, 5, 6, 10, 11) then 1
            when @showListedOrSold = 2 and  id in (2) then 1
        else 0
        end) = 1
1 голос
/ 15 мая 2019

Вы можете создать оператор SQL и затем выполнить его:

declare  @showListedOrSold Int = 1
Declare @vSQL VarChar(200)

Set @vSQL = 'select * from #tbl where id In '
Set @vSQL = @vSQL + 
                    CASE WHEN @showListedOrSold = 0 THEN '(1, 2, 5, 6, 10, 11)'
                         WHEN @showListedOrSold = 1 THEN '(1, 5, 6, 10, 11)' 
                         WHEN @showListedOrSold = 2 THEN '(2)'
                    END

Execute(@vSQL)
0 голосов
/ 15 мая 2019

Вы можете задать его как подзапрос в предложении WHERE:

select *
from table
where @showListedOrSold in (select  (CASE WHEN @showListedOrSold = 0 THEN id IN (1, 2, 5, 6, 10, 11) 
             WHEN @showListedOrSold = 1 THEN id IN (1, 5, 6, 10, 11) 
             WHEN @showListedOrSold = 2 THEN id IN (2) 
      END) as ABCD from table)
...