在WHERE声明中的情况

时间:2013-11-11 17:37:35

标签: sql sql-server-2008 teradata

我对SQL很新,并且遇到了Where语句的问题。我试图查看昨天和昨天一周的支票,除非今天(今天是查询运行的那天)是星期一,那么我想查看星期五和星期五优先。错误消息是“预期'Check_date'和'='之间的内容。

WHERE
    CASE WHEN DAYOFWEEK(date) = 2 
        THEN (a.check_date = DATE - 3 OR a.check_date = DATE - 10)
        ELSE (a.check_date = DATE - 1 OR a.check_date = DATE - 8) END

3 个答案:

答案 0 :(得分:4)

在T-SQL中,CASE表达式,它从其中一个分支返回单个值。它不是语句,不能像其他语言一样用于控制流。你不能把整个条件放在里面。语义差异似乎很小,但行为差异很大。

在这种情况下使用CASE表达式(没有双关语)不会非常有价值,因为它需要多个分支,例如(我只是在猜测,因为你当前的查询并不是很清楚你想要做什么):

WHERE a.checkdate IN 
  (DATEADD(DAY, 0-CASE DATEPART(WEEKDAY, [DATE]) 
    WHEN 2 THEN 3  ELSE 1 END, [DATE]),
  (DATEADD(DAY, 0-CASE DATEPART(WEEKDAY, [DATE]) 
    WHEN 2 THEN 10 ELSE 8 END, [DATE]);

当然,在没有引入CASE表达的情况下将它们组合起来要容易得多:

WHERE 
  (
    DATEPART(WEEKDAY, [DATE]) = 2
    AND a.checkdate IN (DATEADD(DAY, -3, [DATE]), DATEADD(DAY, -10, [DATE]))
  )
  OR
  (
    DATEPART(WEEKDAY, [DATE]) <> 2
    AND a.checkdate IN (DATEADD(DAY, -1, [DATE]), DATEADD(DAY, -8,  [DATE]))
  );

更容易预先定义两个变量(虽然我不确定teradata如何与批次一起使用):

 DECLARE @d1 DATE, @d2 DATE;

 SET @d1 = DATEADD(DAY, -1, [DATE]);
 SET @d2 = DATEADD(DAY, -8, [DATE]);

 IF DATEPART(WEEKDAY, [DATE]) = 2
 BEGIN
   SELECT @d1 = DATEADD(DAY, 2, @d1), @d2 = DATEADD(DAY, 2, @d2);
 END

 SELECT ...
 WHERE a.checkdate IN (@d1, @d2);

答案 1 :(得分:0)

试试这个:

 WHERE
        ((DAYOFWEEK(date) = 2) and (a.check_date = DATE - 3 OR a.chek_date = dateadd(day,-10,DATE) ))
            Or (a.check_date =dateadd(day,-1,DATE) OR a.check_date=dateadd(day,-8,DATE)) 

答案 2 :(得分:0)

如果您使用的是Teradata并且安装了sys_calendar.calendar表,请尝试以下方法:

join sys_calendar.calendar sys_cal
on sys_cal.calendar_date = current_date 

where
     (sys_cal.day_of_week = 2 
      and (   a.check_date = current_date - 3
           OR a.check_date = current_date - 10)
     )
  or (sys_cal.day_of_week ne 2 
      and (   a.check_date = current_date - 1
           OR a.check_date = current_date - 8)
     )