2

我对 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
4

3 回答 3

5

在 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);
于 2013-11-11T17:54:00.807 回答
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)) 
于 2013-11-11T17:43:22.167 回答
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)
     )
于 2013-11-12T20:34:00.623 回答