在SQL Server中,为什么NULL不等于空字符串,也不不等于空字符串?

4

这显然不会返回一行...


(这里的“行”可能指的是数据库中的一行数据)
select 1 where null = ''

但是为什么这个查询也没有返回结果行呢?
select 1 where null <> ''

这两个WHERE条件怎么可能都是“false”呢?
8个回答

5
"这两个WHERE语句怎么可能都是“false”?"
并不是!答案也不是“true”!答案是“我们不知道”。
NULL看作你还不知道的值。
你会打赌它是''吗?
你会打赌它不是''吗?
所以,更安全的做法是声明你还不知道。因此,对于这两个问题的答案不是false,而是我不知道,比如在SQL中使用NULL。"

3
因为这是符合ANSI SQL的SQL Server实例,;-)
在SQL中,NULL与IEEE NaN在比较规则上有些相似:NaN!= NaNNaN == NaN都是false。需要使用一个特殊的运算符IS NULL(对于IEEE FP,“IsNaN”)来检测这些特殊值。(实际上有多种方法可以检测这些特殊值:IS NULL / "IsNaN"只是干净而简单的方法。)
然而,NULL = x更进一步:NULL =/<> x的结果不是false,而是它本身是NULL未知。因此,NOT(NULL = '')也是 NULL未知(或在where上下文中为“false”--请参见注释)。欢迎来到SQL三态逻辑的世界;-)
由于问题涉及SQL Server,因此为了完整起见:如果使用“SET ANSI_NULLS OFF”运行,则可以达到“原始”的TSQL行为。(但请参见顶部的备注/警告。)
“原始”行为(已弃用):
SET ANSI_NULLS OFF;
select 'eq' where null = '';       -- no output
select 'ne' where null <> '';      -- output: ne
select 'not' where not(null = ''); -- output: not; null = '' -> False, not(False) -> True

ANSI-NULLs行为(最近的默认值,请使用):

SET ANSI_NULLS ON;
select 'eq' where null = '';       -- no output
select 'ne' where null <> '';      -- no output
select 'not' where not(null = ''); -- no output; null = '' -> Unknown, not(Unknown) -> Unknown

愉快地编程。


2
NULL = x 的结果为UNKNOWN。在WHERE语境中,其效果是将该行从结果集中移除。在约束上下文中,其效果是对该行的更新不会失败。 - onedaywhen
@onedaywhen 感谢您的更正。我已经适当地更新了答案。 - user166390

2

在进行比较时,NULL有一些非常奇怪的行为 - 维基百科文章解释得很好。简而言之,在true和false之外,还有一个未知值,当SQL进行比较时会返回该值。


1
SQL标准规定对于所有的x(即使x本身是NULL),NULL = x都是false,而SQL Server只是遵循这个标准。如果你想检查某个东西是否为NULL,那么你必须使用x IS NULL或x IS NOT NULL。

1

0

因为与 NULL 进行任何比较都返回 false(或者准确地说:返回 NULL)

由于 NULL 是缺乏信息的表示,你无法确定它是否等于或不等于某个值。


我认为这很奇怪,我假设(信息的缺失)!=(信息)。 - JeremyWeir
1
@jayrdub:这样想:如果你没有一艘宇宙飞船,你怎么能知道那艘宇宙飞船是什么颜色呢?它既不是白色,也不是非白色。 - user330315
2
但我确实拥有一艘宇宙飞船。谢谢,这很有帮助。 - JeremyWeir
准确地说,与“NULL”进行的任何相等比较都会评估为未知。 - onedaywhen
@onedaywhen:有趣。NULL和UNKNOWN之间有什么区别? - user330315
@a_horse_with_no_name:UNKNOWN 是一个逻辑值。NULL 是一个数据值。你不能“返回”一个逻辑值。 - onedaywhen

0

可能会有一点重复,但这是我的两分钱意见:

A. a_horse_with_no_name 的例子(上面的评论)非常好!

B. 以非数学术语来说,NULL 是一个未知值。空字符串是长度为零的字符串 - 因此是一个“已知”值。这就是为什么 NULL 不等于或不不等于空字符串。

C. 由于 NULL 表示未知,不可能比较两个 NULL 值是否相等。如果你不知道 X 的值,也不知道 Y 的值,那么你就不知道它们是否相等。


0

参见SQL-92 8.2比较谓词的说法:

一般规则

  1. 设X和Y是任意两个对应的<row value constructor element>。设XV和YV分别表示X和Y所代表的值。

    情况:

    a) 如果XV或YV是空值,则“X <comp op> Y”是未知的。


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