【问题标题】:why is null not equal to null false为什么null不等于null false
【发布时间】:2010-12-22 11:32:28
【问题描述】:

我正在阅读这篇文章: 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 以获得此问题的答案。

【问题讨论】:

  • 简而言之,anything = NULL 为 NULL(既不是真也不是假)。 anything &lt;&gt; NULL 也是 NULL。

标签: sql database null nullable


【解决方案1】:

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

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

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

【讨论】:

  • 好视角!另一种看待它的方式是,如果“未知 a”等于“未知 b”,那么它们就不可能真的那么未知,因为你对它们有所了解。一种量子力学。
  • @womp:确实,你知道你不知道;)
  • 但是我们不知道NULL 不等于a 吗?将NULL 称为“未知”意味着NULL 的值可能是a。但它没有值,我们知道缺少值不等于存在值。
【解决方案2】:

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

编辑

这里,&lt;&gt; 代表任意二元运算符,NULL 是 SQL 占位符,value 是任意值(NULL不是一个值):

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

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

X = 42 是真、假还是未知,因为您不知道 X 的值(如果 any)是什么? SQL说它是未知的。鉴于两者都是未知的,X = Y 是真、假还是未知? SQL 说结果是未知。它对任何二元关系操作都是这样说的,这只是合乎逻辑的(即使模型中最初没有 NULL)。

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

  • NULL IS NULL -> TRUE
  • NULL IS NOT NULL -> FALSE

【讨论】:

  • 嘿,在阅读了您的解释后,我得到了“我的脑海中出现编译错误”。我的意思是,为什么甚至允许二进制比较呢?如果我写 select * from A where A.xxx &lt;&gt; null 我会得到一个空的结果集。但是,如果我写 select * from A where null 这是一个语法错误。所以用“value null => null”的解释对我来说有些东西不适合我......你能帮我如何思考这个问题的“正确”方式吗?
  • 可能是这样,像value &lt;&gt; null =&gt; falsevalue = null =&gt; false 这样考虑它会更有意义吗?这将避免我正在谈论的类型错误。此外,像这样的人可以推断出 value &lt;&gt; null AND 1=1 之类的含义是什么,而 null AND 1=1 在语法上又会很奇怪......正如我所说,我只是想绕开这个问题。
  • foo OP NULL 被允许,因为 SQL 已损坏。
  • 整个答案是关于这根本没有意义,并且与标准和实际语义相矛盾。另一种看法,回答以下问题:“我手中的东西是一个苹果”。对或错?你能给出的唯一答案是unknown。现在回答这个问题:“我手里有东西”。再说一次,你不知道
  • "that" 毫无意义当然是认为foo != NULLfoo = NULL 都是错误的。他们是未知的
【解决方案3】:

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

【讨论】:

  • 不知道是谁投了反对票。任何涉及nulls 而非is 的比较都将在遵循SQL 标准的数据库上返回false。
  • 我做到了。任何涉及 null 的比较都将返回 NULL
  • @just someone: 是的,比较的“价值”是空的,但由于这个“价值”永远无法真正检查,它的实际估值是错误的。
  • @Adam Robinson:比较结果为空。它不会评估为假。如果确实如此, (v_b = false) 将是真的,但事实并非如此。 if 分支只有在结果为true 时才会被跟踪,所以它看起来结果是假的,但它绝对不是假的。
  • @Adam Robinson:我只是想澄清一下,虽然它永远不会是真的,但它也永远不会是假的。比较结果为 null(技术上:为“未知”)。它不是假的,因为如果它是,你可以否定它并得到真实,这是你做不到的。分支永远不会被采用(或行永远不会匹配),因为它们依赖于真实的值。 Wikipedia explains it better than I do..
【解决方案4】:

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

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

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

【讨论】:

    【解决方案5】:

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

    但是,在处理未列出的 MS Sql Server 时,我会提出一些边缘情况和注意事项。

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

    在 SQL Server 中,可以使用 SET ANSI_NULLS OFF 覆盖有关特定 Null = 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
    

    【讨论】:

      【解决方案6】:

      这是一个快速修复

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

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

      【讨论】:

        【解决方案7】:

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

        问题是:为什么比较结果为 FALSE?

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

        SQL 语言中的无数变态之一。

        此外,必须考虑以下几点:

        如果“unkown”是三元逻辑中的一个逻辑值,那么应该是两个恰好都是“unknown”(的值)的逻辑值之间的相等比较,那么该比较应该产生真的。

        如果逻辑值本身是未知的,那么显然不能通过将值“未知”放在那里来表示,因为这意味着逻辑值是已知的(即“未知”)。也就是说,ao,关系理论如何证明实现 3 值逻辑会提高对 4 值逻辑的要求,4 值逻辑会导致需要 5 值逻辑,等等等等,无穷无尽。

        【讨论】:

          猜你喜欢
          • 2020-04-27
          • 1970-01-01
          • 2015-02-22
          • 2022-11-21
          • 2018-10-08
          • 1970-01-01
          • 1970-01-01
          • 2011-09-05
          • 2010-09-12
          相关资源
          最近更新 更多