为什么null不等于null false
我正在阅读这篇文章: 在SQL中获取null == null
而共识是,当试图testing两个(可空)sql列的平等时,正确的做法是:
where ((A=B) OR (A IS NULL AND B IS NULL))
当A和B为NULL时,(A = B)仍然返回FALSE,因为NULL不等于NULL。 这就是为什么额外的检查是必需的。
什么时候testing不平等? 从上面的讨论来看,这让我想到,为了testing不平等,我需要做一些事情:
WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))
但是,我注意到,这是没有必要的(至less不是在informix 11.5),我可以这样做:
where (A<>B)
如果A和B是NULL,则返回FALSE。 如果NULL不等于NULL,那么不应该返回TRUE?
编辑
这些都是很好的答案,但我想我的问题有点含糊。 请允许我改述一下:
鉴于A或B可以是NULL,是否足以检查它们的不等式
where (A<>B)
或者我需要像这样明确地检查它:
WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))
请参阅此主题以解答此问题。
涉及NULL的关系expression式实际上会再次产生NULL
编辑
这里, <>
代表任意的二元运算符, NULL
是SQL占位符, value
是任何值( NULL
不是一个值):
-
NULL <> value
– >NULL
-
NULL <> NULL
– >NULL
逻辑是: NULL
表示“无值”或“未知值”,因此与任何实际值的比较都是没有意义的。
假设你不知道X
有什么价值(如果有 ), X = 42
真,假还是未知。 SQL说这是未知的。 是X = Y
真,假,还是未知,因为两者都是未知的? SQL说结果是未知的 。 对于任何二元关系操作来说都是如此,这只是逻辑上的(即使模型中的NULL不在第一位)。
SQL还提供了两个一元后缀运算符, IS NULL
和IS NOT NULL
,根据它们的操作数返回TRUE或FALSE。
-
NULL IS NULL
– >TRUE
-
NULL IS NOT NULL
– >FALSE
因为该行为遵循build立的三元逻辑 ,其中NULL被认为是未知值。
如果你认为NULL是未知的,它会变得更加直观:
unknown a
是否等于unknown b
? 没有办法知道,所以: unknown
。
涉及null
所有比较都是未定义的,并且评估为false。 这个想法可以防止null
被评估为等价于null
,也可以防止null
被评估为不等于null
。
简短的回答是… NULL是奇怪的 ,他们并不像你所期望的那样。
这里有一篇很好的关于NULL如何在SQL中工作的论文。 我认为这将有助于提高你对这个话题的理解。 我认为在expression式中处理空值的部分对你尤其有用。
http://www.oracle.com/technology/oramag/oracle/05-jul/o45sql.html
expression式中的空值的默认(ANSI)行为将导致null(有足够的其他答案)。
但是,有一些边缘情况和警告,我将处理与未列出MS MSSQL服务器时。
- 在将值分组在一起的语句中的空值将被视为相等并被分组在一起。
- 在sorting的语句中的空值将被视为相等。
- 在评估查询的不同方面时,在使用distinct的语句中select的空值将被视为相等
在SQL Server中,可以使用SET ANSI_NULLS OFF覆盖关于特定的Null = Nulltesting的expression式逻辑,然后这会给你null值之间的相等 – 这不是推荐的做法,但是确实存在。
SET ANSI_NULLS OFF select result = case when null=null then 'eq' else 'ne' end SET ANSI_NULLS ON select result = case when null=null then 'eq' else 'ne' end
这是一个快速修复
ISNULL(A,0)= ISNULL(B,0)
0可以更改为在您的数据中永远不会发生的事情
“未知数与未知数b相等吗?没有办法知道,所以:未知数”。
问题是:为什么比较收益率是假的?
给定三值逻辑,确实比较合理的是产生UNKNOWN(而不是FALSE)。 但是SQL确实产生FALSE,而不是UNKNOWN。
SQL语言中无数的变态之一。
此外,还必须考虑以下几点:
如果“未知”在三元逻辑中是一个逻辑值,那么两个逻辑值之间的相等比较应该是(未知值),那么这个比较应该是TRUE。
如果逻辑值本身是未知的,那么显然不能通过将值“未知”放在那里来表示,因为这意味着逻辑值是已知的(“未知”)。 也就是说,关系理论如何certificate实现3值逻辑提出了对4值逻辑的要求,4值逻辑导致了对5值逻辑的需要等等。