简体   繁体   English

如何在带有IN子句的WHERE中使用CASE语句?

[英]How to use CASE statement inside a WHERE with an IN clause?

I am trying to do the following (pseudocode since it doesn't compile): 我试图做以下(伪代码,因为它不编译):

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

Basically depending on value of showListedOrSold , it should bring back certain id values. 基本上取决于showListedOrSold值,它应该带回某些id值。

The statement is not liking the IN clause. 声明不喜欢IN子句。 What is the correct syntax for this use case? 这个用例的正确语法是什么?

If you want an "elegant solution", you might want to consider store these values in a table that can be used in your query. 如果您想要“优雅的解决方案”,您可能需要考虑将这些值存储在可在查询中使用的表中。

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;

You could solve this by using OR instead of CASE: 您可以使用OR而不是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))

This starts to get rather complicated. 这开始变得相当复杂。 I might recommend a join approach: 我可能会推荐一种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

You can easily expand this to show all rows if the variable is null : 如果变量为null您可以轻松展开它以显示所有行:

     on (t.slos = @showListedOrSold and
         v.id = s.id
        ) or
        @showListedOrSold is null

the way case works, you'd have to return a value, then check the value. 案例的工作方式,你必须返回一个值,然后检查值。

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

You could construct the SQL statement and then Execute it: 您可以构造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)

You can give it like a sub query in WHERE clause: 你可以像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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM