为什么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 NULLIS 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值逻辑的需要等等。