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

时间:2019-05-15 17:52:12

标签: sql sql-server sql-server-2016

我正在尝试执行以下操作(伪代码,因为它无法编译):

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 个答案:

答案 0 :(得分:7)

如果您需要“优雅的解决方案”,则可能需要考虑将这些值存储在可用于查询的表中。

<div class="case">
  <div class="case-wrapper">
  <span class="sp">Short text</span>
  </div>
</div>

<div class="case">
  <div class="case-wrapper">
  <span class="sp">Overflowing long text, so long that you can't read it at once!</span>
</div>
  </div>

<div class="case">
  <div class="case-wrapper">
  <span class="sp">It will always scroll all the way to the end and will stop there.</span>
</div>
  </div>

答案 1 :(得分:6)

您可以使用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))

答案 2 :(得分:5)

这开始变得相当复杂。我可能会推荐一种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

答案 3 :(得分:2)

大小写的工作方式,您必须返回一个值,然后检查该值。

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

答案 4 :(得分:1)

您可以构造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)

答案 5 :(得分:-1)

您可以像在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)