Where Case语句使用单独的字段

时间:2019-02-18 22:18:53

标签: sql tsql

我很难在此SQL语句中获取where子句以返回适当的记录。基本上,我们有一个表,其中列出了一年中的所有日期以及相关信息。主键是将varchar(8)转换为YYYYMMDD格式的[即执行convert(varchar(8), getdate(), 112)以查看我正在谈论的格式返回]。这是我的声明:

SELECT * FROM [dbo].DimDate
WHERE datekey = 
(
  CASE 
    WHEN 
    (
      SELECT datekey 
      from dimdate 
      where 
        datekey = convert(varchar, getdate(), 112)
    ) = 2 
    THEN 
      convert(varchar, dateadd(dd,-3,getdate()), 112)
    WHEN 
    (
      SELECT datekey 
      from dimdate 
      where 
        datekey = convert(varchar, getdate(), 112)
    ) = 1 
    THEN 
      convert(varchar, dateadd(dd,-2,getdate()), 112)
    ELSE '20190115' 
  END
)
/*
datekey = (CASE [DayOfWeek]
WHEN 1 THEN convert(varchar, dateadd(dd,-3,getdate()), 112)
WHEN 2 THEN convert(varchar, dateadd(dd,-4,getdate()), 112)
ELSE '20190109' END)
-- */
--convert(varchar(8), dateadd(dd,-3,getdate()), 112)

它始终默认为ELSE部分。我已经包括了我使用过的各种尝试中的几种(已注释掉),并从中得到了结果。是的,我已经手动检查了表中的数据以确保其存在。该规范的目标是,如果今天是星期天或星期一,那么我需要在上周五获得记录。 Else语句现在是硬编码的,因为否则我没有返回任何记录。

**我能够同时工作。要回答以下一些评论-是的,我发布的查询的一部分在select语句中有不正确的字段。那是我为论坛修改它的错误。那仍然是行不通的。正在按照我标记为答案的建议使用datepart发布工作版本和另一个版本:

SELECT * FROM [dbo].DimDate
WHERE datekey = 
Case DATEPART(dw, getdate())
    WHEN 1 THEN convert(varchar, dateadd(dd,-3,getdate()), 112)
    WHEN 2 THEN convert(varchar, dateadd(dd,-4,getdate()), 112)
ELSE convert(varchar, getdate(), 112)
END

SELECT * FROM [dbo].DimDate
WHERE datekey = 
    (CASE (SELECT [DayOfWeek] FROM DimDate WHERE datekey = 
convert(varchar, getdate(), 112))
        WHEN 1 THEN convert(varchar, dateadd(dd,-3,getdate()), 112)
        WHEN 2 THEN convert(varchar, dateadd(dd,-4,getdate()), 112)
        ELSE '20190109'
    END)

最后一点,这需要是内联的,因为它用于较大的查询中,返回中等的求和集,这就是为什么我不声明变量等。再次感谢大家的投入和帮助!

1 个答案:

答案 0 :(得分:0)

CASE语句中,比较星期几的方式是错误的。您应该使用DATEPART(DW, date)来获取星期几,但是在提供的SQL语句中,您将比较两个将返回TRUEFALSE的字符串。

您的SQL语句应重组为

SELECT * FROM [dbo].DimDate
WHERE datekey = 
(
  CASE 
    WHEN 
    (
      SELECT DATEPART(DW, getdate())
    ) = 2 
    THEN 
      convert(varchar, dateadd(dd,-3,getdate()), 112)
    WHEN 
    (
      SELECT DATEPART(DW, getdate())
    ) = 1 
    THEN 
      convert(varchar, dateadd(dd,-2,getdate()), 112)
    ELSE '20190115' 
  END
)

我个人将采用以下方法简化SQL语句,因为当前日期是静态的,并且随着数据集变大,它将提高语句的性能。

DECLARE @dow INT = DATEPART(DW, GETDATE())
DECLARE @daysSinceLastFriday INT = CASE 
                                    WHEN 
                                        @dow=2
                                    THEN -3
                                    WHEN 
                                        @dow=1
                                    THEN -2
                                    ELSE
                                        0       -- Assign with the suitable default day of the week 
                                    END;

DECLARE @lastFriday VARCHAR(8) = CONVERT(VARCHAR, DATEADD(dd,@daysSinceLastFriday,GETDATE()), 112)

SELECT * FROM [dbo].DimDate
    WHERE datekey = @lastFriday