案例......当......在WHERE CLAUSE中

时间:2014-02-18 15:24:47

标签: sql sql-server tsql where-clause

我认为我的代码可行,如下:

WHERE cp.OwnerId = 1
AND CASE
    WHEN [CustAccountNote] <> 'n/a' AND [CustRulesDocPath] <> 'n/a' 
    THEN (cp.NAME = 'IQRRulesLinks' OR cp.NAME = 'AccountNote')
END 
AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()

如果[CustAccountNote]和[CustRulesDocPath]都是'n / a',那么我想要做的就是OMIT在THEN语句中的内容。 T-SQL不喜欢我正在做的事情。 (震惊)。

我如何编写这个WHERE语句,以便如果这些字段结果中的两个都是'n / a',它将不会运行“cp.Name = .....”?

6 个答案:

答案 0 :(得分:1)

你无法完全按照自己的意愿去做,因为Case只能返回一个值,但你可以破解它:

WHERE cp.OwnerId = 1
AND 
(
    cp.NAME = 'IQRRulesLinks' 
    OR cp.NAME = 'AccountNote'
    Or 1 =  CASE
                WHEN [CustAccountNote] = 'n/a' AND [CustRulesDocPath] = 'n/a' Then 1
                Else 0
            End
)
AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()

基本上,这里你要么说Name必须等于IQRRulesLinks,要么Name必须等于Name 1必须等于Case语句确定的值。当CustAccountNote为n / a或CustRulesDocPath为n / a时,该值为1 - 有效地使整个括号内的where子句短路。

答案 1 :(得分:1)

这样的事情?

WHERE cp.OwnerId = 1
  AND (    ([CustAccountNote] = 'n/a' AND [CustRulesDocPath] = 'n/a')
        or (cp.NAME = 'IQRRulesLinks' OR cp.NAME = 'AccountNote')
      )
  AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()

因此,如果CustAccountNoteCustRulesDocPath 等于'n / a',那么cp.name的值是什么并不重要。

或者,如果任何 CustAccountNoteCustRulesDocPath不等于'n / a',那么cp.name必须是'IQRRulesLinks'或'AccountNote'。

答案 2 :(得分:0)

尝试使用AND&amp; OR子句中的WHERE

WHERE cp.OwnerId = 1
AND (([CustAccountNote] <> 'n/a' AND [CustRulesDocPath] <> 'n/a' 
    AND (cp.NAME = 'IQRRulesLinks' OR cp.NAME = 'AccountNote'))
    OR 
    ([CustAccountNote] = 'n/a' AND [CustRulesDocPath] = 'n/a'))
AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()

使用示例数据检查SQL Fiddle

答案 3 :(得分:0)

根据作者的要求,如果另外两列不是n / a,则不评估两个名称条件,这个case语句将正确实现所请求的逻辑快捷方式,这是我个人认识的唯一方法。这个任务。此外,由于名称基于两个等效比较,因此使用IN运算符是编写特定段的更简单方法。

WHERE cp.OwnerId = 1
  AND (CASE
    WHEN [CustAccountNote] <> 'n/a' AND [CustRulesDocPath] <> 'n/a' 
      THEN 1
    WHEN cp.NAME IN ('IQRRulesLinks', 'AccountNote')
      THEN 1
    ELSE 0 END) = 1
  AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()

答案 4 :(得分:0)

逻辑上,A => B相当于(NOT A) OR B。因此,您可以按如下方式重写SQL:

WHERE cp.OwnerId = 1
AND ([CustAccountNote] = 'n/a'
    OR [CustRulesDocPath] = 'n/a'
    OR cp.NAME = 'IQRRulesLinks' 
    OR cp.NAME = 'AccountNote')
AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()

答案 5 :(得分:0)

I have replaced the last part of `THEN` Statement with `Coalesce` function.


  WHERE cp.OwnerId = 1
    AND (CASE
        WHEN [CustAccountNote] <> 'n/a' AND [CustRulesDocPath] <> 'n/a'
           THEN cp.NAME = COALESCE(cp.NAME,'IQRRulesLinks', 'AccountNote')
    END )
    AND pp.lastupdated BETWEEN '01/01/2013' AND GETDATE()