在IN子句中使用CASE语句

时间:2012-06-27 17:58:05

标签: sql sql-server sql-server-2008 tsql

是否可以在IN子句中使用CASE语句?

这是我试图正确编译的简化版本:

SELECT * FROM MyTable 
WHERE StatusID IN (
CASE WHEN @StatusID = 99 THEN (5, 11, 13)
ELSE (@StatusID) END )

谢谢!

4 个答案:

答案 0 :(得分:24)

CASE仅返回标量值。你可以这样做。 (我假设,根据您的示例,当@StatusID = 99时,StatusID值为99不匹配。)

select *
from MyTable
where (@StatusID = 99 and StatusID in (5, 11, 13))
    or (@StatusID <> 99 and StatusID = @StatusID)

答案 1 :(得分:3)

没有。相反,你可以把它放在外面

SELECT *
FROM MyTable
WHERE 1 = (CASE WHEN @StatusID = 99 and StatusId in (5, 11, 13) then 1
                WHEN coalesce(@StatusId, 0) <> 99 and StatusId in (@StatusID) then 1
                ELSE 0
           END)

你也可以在没有case语句的情况下写这个。

另一个选项是动态SQL,您实际上使用SQL语句创建一个字符串,然后执行它。但是,在这种情况下,动态SQL似乎有些过分。

答案 2 :(得分:0)

我以为我会使用表值构造函数尝试这种方式 - 在以下情况下不允许使用TVC吗?

SELECT * 
FROM MyTable  
WHERE StatusID IN 
   ( 
   SELECT 
       CASE 
         WHEN @StatusID = 99 THEN (values(5),(11),(13)) t(StatusID )
         ELSE @StatusID 
   END  
   ) 

答案 3 :(得分:0)

你可以使用TVC来做到这一点,但方法略有不同。它没有使用案例,但在有许多可供选择的选项的情况下它会更好地扩展:

SELECT * 
FROM MyTable  
join (values 
      (99,5),(99,11),(99,13),
      (@StatusID , @StatusID)    
    ) t(k,v) on t.k= @StatusID and t.v = StatusID)

或者如果你需要where子句中的所有内容:

SELECT * 
FROM MyTable  
WHERE exists (
    select 1
    from (values 
      (99,5),(99,11),(99,13),
      (@StatusID , @StatusID)    
    ) t(k,v)
    where t.k= @StatusID and t.v = StatusID)