在某些情况下(如果' a',' b')ELSE(' c',' d')结束时的情况下Col1

时间:2014-12-22 15:46:52

标签: sql tsql

得到一个简单的问题。这显然不是有效的T-SQL语法:

SELECT Col1
FROM SomeTable
WHERE Col2 IN
    CASE WHEN someCondition THEN
        ('a', 'b')
    ELSE
        ('c', 'd')
    END

做一些简单的事情,例如围绕括号中的CASE WHEN...END块,添加SELECT个关键字,将Col2 IN剪切并粘贴到每个案例处理程序等中,等等。太完美了。老实说这看起来应该可行,但CASE语句可能会在SQL中遇到一些尴尬的限制。

这种语法有什么问题,如何修复?是否有任何真正的原因导致上述语法被破坏(可能导致一个小的调整,将解决上述问题),或者这只是语言设计者任意"忘记"处理(可能需要一种与上述完全不同的方法)?

请注意,某些应用程序涉及someCondition采用以下形式:

(SELECT SomeCol FROM OtherTable WHERE id = n) = 'someVal'

我不确定在同一个查询中复制那种子选择和比较是否容易导致它实际上在SQL中的每个位置被单独调用,但即使它只被称为多个没有重复的时候,写两次仍然感觉不好。我想它可以运行一次并存储在一个变量中,但这也是额外的代码。

3 个答案:

答案 0 :(得分:3)

SELECT Col1
FROM SomeTable
WHERE
    ( someCondition and Col2 in ('a','b') ) or ( not someCondition and Col2 in ('c','d') )

答案 1 :(得分:2)

更改where逻辑以消除case

where (( someCondition ) and Col2 in ('a', 'b')) or
      (not ( someCondition) and Col2 in ('c', 'd') )

(此版本假定someCondition永远不会NULL。)

答案 2 :(得分:1)

CASE的结果必须是值。

IN的RHS可能是SELECT的结果,因此您可以执行以下操作:

declare @Which as Int = 0;
select *
  from ( values ( 0 ), ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ) ) as Things( Thing )
  where Thing in (
    select * from ( values ( 1 ), ( 2 ) ) as Bar( Foo ) where @Which = 0
    union
    select * from ( values ( 3 ), ( 4 ) ) as Bar( Foo ) where @Which = 1 )