2014-01-16 75 views
8

我已经看过很多类似的问题在这里和其他地方问过,我不知道如何推断他们对我所需要的内容,所以我选择要求我的场景。在WHERE子句中使用CASE语句

基本上,我需要检查一行的日期是否在某个日期之前。日期(这个早于我,我无能为力,尽管不喜欢这个系统)只是作为一个单一的数字来存储,这个数字对应着今年的天数。例如,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.

+1

T-SQL中的'CASE'是一个**表达式**,它可以返回几个**原子值中的一个** - 但它不能返回或处理代码块,也不能返回半个WHERE子句。 –

回答

7

你的where子句应该是这个样子,如果你想使用一个case语句里面它:所有

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 
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 

这似乎工作!