【问题标题】:SQL Server Case Statement when IS NULLIS NULL 时的 SQL Server 案例语句
【发布时间】:2013-07-25 21:39:19
【问题描述】:

我正在尝试在 SQL Server 中执行 IF 语句类型函数。

如果字段中有 NULL,我希望它从其中一个表中取出一个字段并添加 10 天。

如果可能,创建另一列并添加 30 天。

SELECT DISTINCT
    B.[ID],
    MAX(A.[START DATE]),
    B.[STAT],
    C.[POST DATE],
    CASE
          WHEN (C.[POST DATE] BETWEEN C.[EVENT DATE]+10 AND C.[EVENT DATE]+30) THEN 'GOOD'
          END AS [BETTER VISIT],
    CASE
          WHEN B.[STAT] IS NULL THEN (C.[EVENT DATE]+10)
          ELSE '-'
          END AS [DATE]
FROM 
    #TEMP1 A
    FULL OUTER JOIN #TEMP2 B
    ON A.[ID]=B.[ID]
    FULL OUTER JOIN #TEMP3 C
    ON A.[ID]=C.[ID]
GROUP BY
    B.[ID],
    B.[STAT],
    C.[POST DATE],
    C.[EVENT DATE]
ORDER BY
    A.[START DATE] DESC

结果看起来有点像:

    ID  START DATE   STAT    POST DATE    BETTER VISIT    DATE         DATE2
    ---------------------------------------------------------------------------
    1   2013-01-01   GOOD    2013-11-01   GOOD            -            -
    2   2013-03-01   NULL    NULL         NULL            2013-03-11   2013-03-31

【问题讨论】:

  • 你现在得到的输出有什么问题?
  • Msg 242, Level 16, State 3, Line 1 将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。
  • IsNull 可能会有所帮助。 msdn.microsoft.com/en-us/library/ms184325.aspx
  • 我将其更改为 ISNULL,现在错误为:Msg 4145, Level 15, State 1, Line 10 在预期条件的上下文中指定的非布尔类型表达式,靠近 'ISNULL '。

标签: sql sql-server sql-server-2008


【解决方案1】:
CASE WHEN B.[STAT] IS NULL THEN (C.[EVENT DATE]+10)   -- Type DATETIME
     ELSE '-'                                         -- Type VARCHAR
     END AS [DATE]

您需要为字段选择一种或另一种类型,字段类型不能因行而异。 最简单的就是去掉ELSE '-',让它隐式获取NULL的值,而不是第二种情况。

【讨论】:

  • 谢谢,我明天试试。
  • 我试过这个并且查询运行,但它返回一个 NULL 而不是在为 NULL 的 [STAT] 字段上返回一个值 [EVENT DATE]+10
  • @caffaddt 你能用一些示例数据设置一个 SQLfiddle 吗?我只修复了您的查询的语法,如果没有看到一些输入数据,我就无法完全看到您想要的结果中的逻辑。
  • 我可以告诉你的是ID(char)存储在一个真实的表中,EVENT DATE(日期时间)也是如此,STAT(varchar)是另一个临时表中的as CASE语句创建的列, POST DATE 也存储在真实表中,BETTER VISIT (varchar) 来自该表中的 CASE 语句。这有点帮助吗?我对 SQL 还很陌生,所以我需要一段时间才能在该站点上为您构建架构。
  • @caffaddt 设置一个最小的测试,我得到一个 NULL stat 的日期。 sqlfiddle.com/#!3/80015/1
【解决方案2】:

我同意 Joachim 的观点,即您应该将连字符替换为 NULL。但是,如果您确实需要连字符,请将日期转换为字符串:

(CASE WHEN B.[STAT] IS NULL
      THEN convert(varchar(10), C.[EVENT DATE]+10, 121)
      ELSE '-'
 END) AS [DATE]

另外,distinct 在您的 select 语句中是不必要的。 group by 已经为您完成了这项工作。

【讨论】:

  • 这会运行,但不会返回 DATE 的值,它只是给所有内容一个 null。
【解决方案3】:

您可以使用IIF(我认为来自 SQL Server 2012)

SELECT IIF(B.[STAT] IS NULL, C.[EVENT DATE]+10, '-') AS [DATE]

【讨论】:

    【解决方案4】:
      case isnull(B.[stat],0)
      when 0 then dateadd(dd,10,(c.[Eventdate]))
      end
    

    如果你想增加 30 天,你可以在 else 语句中添加。

    【讨论】:

    • 我试过这个并得到这个消息:消息 245,级别 16,状态 1,第 1 行将 varchar 值 'STAT' 转换为数据类型 int 时转换失败。
    • 您尝试使用 cast 或 convert 函数来更改要比较的数据类型。
    【解决方案5】:

    在这种情况下,您可以使用 ISNULL() 函数代替 CASE 表达式

    ISNULL(B.[STAT], C.[EVENT DATE]+10) AS [DATE]
    

    【讨论】:

      【解决方案6】:

      在日期时间数据类型下定义的列中不接受 ELSE 语句中的连字符。你可以:

      a) 将 CAST 包裹在 [stat] 字段周围,以将其转换为日期的 varchar 表示

      b) 使用 9999-12-31 之类的日期时间作为 ELSE 值。

      【讨论】:

        【解决方案7】:

        看一下 ISNULL 函数。它可以帮助您将 NULL 值替换为其他值。 http://msdn.microsoft.com/en-us/library/ms184325.aspx

        【讨论】:

          【解决方案8】:

          mssql 的 Mahesh 解决方案略有不同:

          case when isnull(B.[stat],0) = 0 
               then dateadd(dd,10,(c.[Eventdate]))  
          end
          

          【讨论】:

          猜你喜欢
          • 2014-06-19
          • 1970-01-01
          • 1970-01-01
          • 2011-05-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多