【问题标题】:Return NULL if calculated value falls within a range如果计算值在某个范围内,则返回 NULL
【发布时间】:2019-08-26 19:21:31
【问题描述】:

我正在对日期字段执行相当简单的计算,如果日期早于预定义日期,我想返回 NULL 值。本质上,我正在寻找使用除相等以外的运算符来执行NULLIF 的最有效方法。

下面是我想做的一个例子(显然语法失败):

SELECT
    Id,
    NULLIF(DATEADD(DAY, -180, SurveyDate),  
        {LESS THAN} '20190101')
FROM dbo.Vendor

我使用以下查询获得了所需的结果,但它似乎有点笨拙和冗长:

SELECT
    Id,
    CASE WHEN DATEADD(DAY, -180, SurveyDate) < '20190101'
        THEN NULL
    ELSE
        DATEADD(DAY, -180, SurveyDate)
    END
FROM dbo.Vendor

【问题讨论】:

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


    【解决方案1】:

    您可以做的简化是删除CASE 语句的ELSE 部分:

    CASE WHEN DATEADD(DAY, -180, SurveyDate) >= '20190101' THEN DATEADD(DAY, -180, SurveyDate) END
    

    我看不出你如何只调用函数DATEADD() 而不会增加代码的复杂性。

    【讨论】:

    • 感谢您添加意见。我觉得我会被困在对 DATEADD() 的两次调用中,但我不确定是否有一个 NULLIF() 类型的函数适用于非等式运算符。
    【解决方案2】:

    您可以放置​​一个内联 IIF 语句。让它不那么“笨重”

    SELECT Id, IIF(DATEADD(DAY, -180, SurveyDate) < '20190101', NULL, DATEADD(DAY, -180, SurveyDate)) AS SurveyDate
    FROM dbo.Vendor
    

    【讨论】:

    • IIF 于 2012 年推出,不适用于旧版本。
    【解决方案3】:

    首先,是时候升级数据库服务器了。
    请注意,2008 和 2008 r2 版本的扩展支持已于 2019 年 7 月 9 日结束 - 这意味着不再有更新,甚至不会开发安全补丁(当然,即使在扩展支持结束后,Microsoft 仍保留发布安全补丁的权利)。
    欲了解更多信息,请阅读 RedGate 上的The End of SQL Server 2008 and 2008 R2 Extended Support

    话虽如此,对于 2008 r2,您没有太多选择 - 案例表达式可能是您唯一可行的选择。
    但是,如果您不想写两次dateadd,您可以像这样使用cross apply

    SELECT
    Id,
    CASE WHEN TargetDate < '20190101'
        THEN NULL
    ELSE
       TargetDate
    END
    FROM dbo.Vendor
    CROSS APPLY
    (
        SELECT DATEADD(DAY, -180, SurveyDate) As TargetDate
    ) As td
    

    在这种简单的情况下,这可能看起来有点矫枉过正,但当您有一个复杂的表达式或多个计算列时,cross apply 就派上用场了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-14
      • 2023-01-13
      • 2018-10-16
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多