检查CASE语句中的空日期,我错在哪里了?

40

我的源表格长这样

Id     StartDate
1      (null)
2      12/12/2009
3      10/10/2009

我想创建一个选择语句,选择上述内容,但如果日期不为空,还需要添加一个额外的列来显示一个varchar,例如:

Id     StartDate    StartDateStatus
1      (null)       Awaiting
2      12/12/2009   Approved
3      10/10/2009   Approved

我在我的查询语句中有以下内容,但它似乎不起作用。即使日期中存在一些空值,所有状态都被设置为已批准

        select
             id,
             StartDate,
        CASE StartDate
        WHEN null THEN 'Awaiting'
        ELSE 'Approved' END AS StartDateStatus
        FROM myTable

我的查询结果看起来像:

Id     StartDate    StartDateStatus
1      (null)       Approved
2      12/12/2009   Approved
3      10/10/2009   Approved
4      (null)       Approved
5      (null)       Approved

StartDate是一个smalldatetime,是否有任何例外需要特殊处理?

谢谢

2个回答

89

尝试:

select
     id,
     StartDate,
CASE WHEN StartDate IS NULL
    THEN 'Awaiting'
    ELSE 'Approved' END AS StartDateStatus
FROM myTable

当 StartDate = NULL 时,你的代码将执行一个操作。


NULL 永远不等于 NULL(因为 NULL 是缺少值)。NULL 也永远不会不等于 NULL。上述语法是 ANSI SQL 标准,相反的语法应该是 StartDate IS NOT NULL

你可以运行以下代码:

SELECT CASE WHEN (NULL = NULL) THEN 1 ELSE 0 END AS EqualityCheck,
CASE WHEN (NULL <> NULL) THEN 1 ELSE 0 END AS InEqualityCheck,
CASE WHEN (NULL IS NULL) THEN 1 ELSE 0 END AS NullComparison

而这将返回:

EqualityCheck = 0
InEqualityCheck = 0
NullComparison = 1

为了完整起见,在SQL Server中,您可以:

SET ANSI_NULLS OFF;

这将导致您的相等比较按不同的方式工作:

SET ANSI_NULLS OFF

SELECT CASE WHEN (NULL = NULL) THEN 1 ELSE 0 END AS EqualityCheck,
CASE WHEN (NULL <> NULL) THEN 1 ELSE 0 END AS InEqualityCheck,
CASE WHEN (NULL IS NULL) THEN 1 ELSE 0 END AS NullComparison

返回:

EqualityCheck = 1
InEqualityCheck = 0
NullComparison = 1

但我强烈建议不要这样做。随后维护你的代码的人可能会被迫追踪你并伤害你...

而且,它将不再适用于即将推出的 SQL Server 版本:

https://msdn.microsoft.com/en-GB/library/ms188048.aspx


为什么“ColumnName = NULL”不起作用?为什么这样的语法不被接受? - Paweł Brewczynski
一个非常古老的评论 - 但答案是因为NULL实际上是未知的。如果你写一个简单的查询,你会发现NULL <> NULL。选择CASE WHEN NULL = NULL THEN 1 ELSE 0 END AS IsNullEqual - Simon Hellings

5
select Id, StartDate,
Case IsNull (StartDate , '01/01/1800')
When '01/01/1800' then
  'Awaiting'
Else
  'Approved'
END AS StartDateStatus
From MyTable

如果StartDate = '01/01/1800',结果将是'等待中'。 - Xordal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接