在WHERE子句中使用CASE语句

时间:2014-01-16 20:59:53

标签: sql-server-2008 case where

我在这里和其他地方看过很多类似的问题,我不知道如何推断他们对我需要的东西的说法,所以我选择了问我的情景。

基本上,我需要检查一行的日期是否在某个日期之前。日期,(这在我之前,尽管不喜欢系统,我无能为力)只是存储为一个数字,对应于一年中的天数。例如,1月1日是1月,2月1日是32等等...所以,通过将该数字添加到12/31 /来计算日期。我遇到的问题是,当我检查一个跨越新年的时期时,它会带回(例如)今年12月29日,而不是最后一年。我在SELECT中遇到了这个并且CASE语句工作正常。但是,在WHERE子句中,它没有按预期工作。在where子句中,我需要检查以确保它不是一个周末。 (同样,代码早于我,我无法改变太多,可悲的是)

所以,我现在在WHERE子句中有这个:

CASE 
    WHEN (dateadd(dd, t.periodid, '12/31/2013') > '01/24/2014') THEN AND (DATEPART(DW, convert(varchar, dateadd(dd, t.periodid, '12/31/2012'), 107)) NOT IN (1,7) OR t.periodid IS NULL) 
    WHEN (dateadd(dd, t.periodid, '12/31/2013') <= '01/24/2014') THEN AND (DATEPART(DW, convert(varchar, dateadd(dd, t.periodid, '12/31/2013'), 107)) NOT IN(1,7) OR t.periodid IS NULL)    
END

(即:如果日期大于该期间的最后一天,请将该数字添加到两年前并检查是否是周末。否则,将其添加到上一年的12/31并检查是否是周末。)

我认为我认为它失败了,因为我的情况应该更像是:

AND X = CASE.....

但我不知道在这种情况下该放什么X。

2 个答案:

答案 0 :(得分:7)

如果你想在其中使用case语句,那么你的where子句看起来应该是这样的:

WHERE 
(CASE 
    WHEN (dateadd(dd, t.periodid, '12/31/2013') > '01/24/2014') AND (DATEPART(DW, convert(varchar, dateadd(dd, t.periodid, '12/31/2012'), 107)) NOT IN (1,7) OR t.periodid IS NULL) THEN 1
    WHEN (dateadd(dd, t.periodid, '12/31/2013') <= '01/24/2014') AND (DATEPART(DW, convert(varchar, dateadd(dd, t.periodid, '12/31/2013'), 107)) NOT IN(1,7) OR t.periodid IS NULL) THEN 1
    ELSE 0   
END) = 1

答案 1 :(得分:5)

谢谢大家。在我回来查看更多答案之前,我终于想到了这一点。

我最终这样做了:

    AND 1 = 
    CASE WHEN (dateadd(dd, t.periodid, '12/31/2013') > '01/24/2014') AND (DATEPART(DW, convert(varchar, dateadd(dd, t.periodid, '12/31/2012'), 107)) NOT IN(1,7) OR t.periodid IS NULL)
    THEN 1 
    WHEN (dateadd(dd, t.periodid, '12/31/2013') <= '01/24/2014') AND (DATEPART(DW, convert(varchar, dateadd(dd, t.periodid, '12/31/2013'), 107)) NOT IN(1,7) OR t.periodid IS NULL)
    THEN 1
    END

似乎有效!