为什么null不等于null false

时间:2009-12-02 16:12:09

标签: sql database null nullable

我正在读这篇文章: Get null == null in SQL

并且一致认为,当尝试测试两个(可为空)sql列之间的相等性时,正确的方法是:

where ((A=B) OR (A IS NULL AND B IS NULL))

当A和B为NULL时,(A = B)仍然返回FALSE,因为NULL不等于NULL。这就是需要额外检查的原因。

测试不平等时怎么样?在上面的讨论之后,它让我认为,为了测试不平等,我需要做类似的事情:

WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))

但是,我注意到这没有必要(至少在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))

请参阅此thread以获取此问题的答案。

7 个答案:

答案 0 :(得分:34)

因为该行为遵循已建立的ternary logic,其中NULL被视为未知值。

如果你认为NULL是未知的,它会变得更加直观:

unknown a是否等于unknown b?没有办法知道,所以:unknown

答案 1 :(得分:26)

涉及NULL的关系表达式实际上再次产生NULL

修改

此处,<>代表任意二元运算符,NULL是SQL占位符,value是任何值(NULL 不是一个值):

  • NULL <> value - &gt; NULL
  • NULL <> NULL - &gt; NULL

逻辑是:NULL表示“无值”或“未知值”,因此与任何实际的任何比较都没有意义。

X = 42是真,假还是未知,因为您不知道什么值(如果任何X成立? SQL说这是未知的。是X = Y是真的,假的还是未知的,因为两者都是未知的? SQL表示结果是 unknown 。并且它对于任何二进制关系操作都这样说,这只是逻辑的(即使模型中的NULL不在第一位)。

SQL还提供了两个一元后缀运算符IS NULLIS NOT NULL,它们根据操作数返回TRUE或FALSE。

  • NULL IS NULL - &gt; TRUE
  • NULL IS NOT NULL - &gt; FALSE

答案 2 :(得分:7)

涉及null的所有比较都是未定义的,并且评估为false。这个想法阻止null被评估为等同于null,也阻止null被评估为等同于null

答案 3 :(得分:4)

简短的回答是...... NULL很奇怪,它们的行为并不像你期望的那样。

这是关于NULL如何在SQL中工作的好文章。我认为这有助于提高您对该主题的理解。我认为在表达式中处理空值的部分对你来说特别有用。

http://www.oracle.com/technology/oramag/oracle/05-jul/o45sql.html

答案 4 :(得分:3)

表达式中空值的默认(ANSI)行为将导致为null(对于这种情况,还有足够的其他答案)。

然而,在处理未列出的MS Sql Server时,我会提出一些边缘情况和警告。

  • 将值组合在一起的语句中的空值将被视为相等并组合在一起。
  • 排序它们的语句中的空值将被视为相等。
  • 在评估查询的不同方面时,在使用distinct的语句中选择的空值将被视为相等

在SQL Server中可以使用SET ANSI_NULLS OFF来覆盖关于特定Null = Null测试的表达式逻辑,这将使您在空值之间获得相等 - 这不是推荐的移动,但确实存在。 / p>

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

答案 5 :(得分:2)

这是一个快速修复

ISNULL(A,0)= ISNULL(B,0)

0可以更改为数据中永远不会发生的事情

答案 6 :(得分:0)

“未知等于未知b?没有办法知道,所以:未知。”

问题是:为什么比较产生假?

鉴于三值逻辑,比较产生UNKNOWN(不是FALSE)确实是明智的。但SQL确实会产生FALSE,而不是UNKNOWN。

SQL语言中无数的异常之一。

此外,必须考虑以下因素:

如果“unkown”是三元逻辑中的逻辑值,则应该是两个逻辑值之间的相等比较,这两个逻辑值恰好是(“未知”的值),然后该比较应该产生TRUE。

如果逻辑值本身未知,那么显然无法通过将值“未知”置于其中来表示,因为这意味着逻辑值已知(为“未知”)。也就是说,关系理论如何证明实现3值逻辑提出了对4值逻辑的要求,4值逻辑导致需要5值逻辑等等无限期。