为什么 NULL = NULL 在 SQL Server 中计算结果为 false

发布于 2024-08-14 01:36:34 字数 183 浏览 5 评论 0 原文

在 SQL Server 中,如果 where 子句中有 nullParam=NULL,则其计算结果始终为 false。这是违反直觉的,给我带来了很多错误。我确实知道 IS NULLIS NOT NULL 关键字是正确的方法。但为什么 SQL Server 会这样呢?

In SQL server if you have nullParam=NULL in a where clause, it always evaluates to false. This is counterintuitive and has caused me many errors. I do understand the IS NULL and IS NOT NULL keywords are the correct way to do it. But why does SQL server behave this way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

以酷 2024-08-21 01:36:34

在这种情况下,将 null 视为“未知”(或“不存在”)。在这两种情况下,您都不能说它们相等,因为您不知道它们的值。因此,null=null 的计算结果为 false(false 或 null,具体取决于您的系统),因为您不知道表示它们相等的值。此行为在 ANSI SQL-92 标准中定义。

编辑:
这取决于您的 ansi_nulls 设置。如果你关闭了 ANSI_NULLS,这将评估为 true。运行以下代码作为示例...

set ansi_nulls off

if null = null
    print 'true'
else
    print 'false'


set ansi_nulls ON

if null = null
    print 'true'
else
    print 'false'

Think of the null as "unknown" in that case (or "does not exist"). In either of those cases, you can't say that they are equal, because you don't know the value of either of them. So, null=null evaluates to not true (false or null, depending on your system), because you don't know the values to say that they ARE equal. This behavior is defined in the ANSI SQL-92 standard.

EDIT:
This depends on your ansi_nulls setting. if you have ANSI_NULLS off, this WILL evaluate to true. Run the following code for an example...

set ansi_nulls off

if null = null
    print 'true'
else
    print 'false'


set ansi_nulls ON

if null = null
    print 'true'
else
    print 'false'
半透明的墙 2024-08-21 01:36:34

弗兰克几岁了?我不知道(空)。

雪莉几岁了?我不知道(空)。

弗兰克和雪莉同龄吗?

正确答案应该是“我不知道”(空),而不是“不”,因为弗兰克和雪莉可能年龄相同,我们根本不知道。

How old is Frank? I don't know (null).

How old is Shirley? I don't know (null).

Are Frank and Shirley the same age?

Correct answer should be "I don't know" (null), not "no", as Frank and Shirley might be the same age, we simply don't know.

表情可笑 2024-08-21 01:36:34

在这里我希望澄清我的立场。

NULL = NULL 计算结果为 FALSE 是错误的。黑客和先生正确回答了NULL
这就是原因。 Dewayne Christensen 在对

既然已经是十二月了,我们就用
季节性的例子。我有两件礼物
在树下。现在,你告诉我,如果我
是否有两个相同的东西。

它们可以不同,也可以相同,你不知道,直到有人打开两件礼物。谁知道?您邀请了两个互不相识的人,但他们都给了您同样的礼物 - 罕见,但并非不可能§

那么问题来了:这两个 UNKNOWN 呈现是否相同(相等,=)?正确答案是:未知(即NULL)。

此示例旨在演示“..(falsenull,具体取决于您的系统)..”是正确答案 - 它不是,只有NULL在3VL中是正确的(或者你可以接受给出错误答案的系统吗?)

这个问题的正确答案

  • 三值逻辑(3VL)是违反直觉的(请参阅 Stackoverflow 和其他论坛上关于此主题的无数其他问题来确定);
  • 基于 SQL 的 DBMS 通常甚至不尊重 3VL,它们有时会给出错误的答案(如原发帖者所言,SQL Server 在这种情况下就是这样做的)。

所以我重申:SQL 没有任何好处强迫人们解释相等性的自反属性,它指出:

对于任何 x,x = x §§(用简单的英语来说:无论讨论的宇宙是什么,一个“事物”总是等于它自己< /strong>)。


.. 在 3VL 中(TRUEFALSENULL)。人们的期望会符合2VL(TRUEFALSE,即使在SQL中也对所有其他值有效),即x = x对于任何可能的 x 值,始终评估为 TRUE - 无例外。

另请注意,NULL 是有效的“非值”(正如其辩护者所假装的那样),可以将其指定为属性值(??)作为关系变量的一部分。因此,它们是每种类型(域)可接受的值,而不仅仅是逻辑表达式类型的值。

这就是我的观点NULL作为值,是一个“奇怪的野兽”。不委婉地说,我更愿意说:废话

我认为这个表述更清晰,也更没有争议——对不起,我的英语水平很差。

这只是 NULL 的问题之一。如果可能的话,最好完全避免它们。

§我们在这里关心价值,因此两个礼物始终是两个不同的物理对象这一事实并不是一个有效的反对意见;如果您不相信,我很抱歉,这不是解释值和“对象”语义之间差异的地方(关系代数从一开始就有值语义 - 请参阅 Codd 的信息原理;我认为一些 SQL DBMS 实现者不这样做甚至不关心常见的语义)。

§§据我所知,这是自古以来就被接受的公理(以某种形式,但总是以 2VL 进行解释),并且完全因为它是如此直观。 3VL(现实中的逻辑家族)是最近的发展(但我不确定第一次开发的时间)。

旁注:如果有人介绍Bottom单位Option 类型试图证明 SQL NULL 的合理性,只有经过相当详细的检查后我才会确信,该检查将显示带有 NULL 的 SQL 实现如何拥有健全的类型系统,并最终澄清什么是 NULL(这些“值”) -不完全价值观”)确实如此。


下面我将引用一些作者的观点。 任何错误或遗漏
可能是我的,而不是原作者的。

Joe Celko on SQL NULLs

我看到 Joe Celko 经常在这个论坛上被引用。显然他是这里一位备受尊敬的作家。所以,我对自己说:“他写了哪些关于 SQL NULL 的内容?他如何解释 NULL 的众多问题?”。我的一位朋友有一本Joe Celko 的《聪明人 SQL:高级 SQL 编程,第三版》 的电子书。让我们来看看。

首先,目录。最让我印象深刻的是 NULL 在各种不同的上下文中被提及的次数:

3.4 算术和 NULL 109
3.5 值与 NULL 之间的转换 110
3.5.1 NULLIF() 函数 110
6 个 NULL:SQL 185 中丢失数据
6.4 比较 NULL 190
6.5 NULL 和逻辑 190
6.5.1 子查询谓词中的 NULL 191
6.5.2 标准 SQL 解决方案 193
6.6 数学和 NULL 193
6.7 函数和 NULL 193
6.8 NULL 和宿主语言 194
6.9 NULL 的设计建议 195
6.9.1 避免主机程序出现 NULL 197
6.10 关于多个 NULL 值的注意事项 198
10.1 IS NULL 谓词241
10.1.1 NULL 的来源 242
...

等等。这对我来说是“令人讨厌的特殊情况”。

出于版权原因,我将摘录本书中的一些案例来探讨其中的一些案例,试图将自己限制在本质上。我认为这些引用属于“合理使用”原则,它们甚至可以刺激购买这本书 - 所以我希望没有人会抱怨(否则我将需要删除其中的大部分,如果不是全部)。此外,出于同样的原因,我将避免报告代码片段。对此感到抱歉。购买这本书来阅读有关数据推理的内容。

页码位于后面括号内。

NOT NULL 约束 (11)

最重要的列约束是 NOT NULL,它禁止
在列中使用 NULL。定期使用此约束,并删除
只有当你有充分的理由时才这样做。它将帮助您避免
当您对数据进行查询时,NULL 值会变得更加复杂。

它不是一个值;它是一个标记,用于保存值可能所在的位置。

这又是“有价值但不完全有价值”的废话。其余的对我来说似乎很明智。

(12)

简而言之,NULL 会导致 SQL 中出现很多不规则特征,我们将对此进行讨论
之后。最好的办法就是记住 NULL 的情况和规则
当你无法避免它们时。

关于 SQL、NULL 和无限:

(104) 第 3 章:SQL 中的数字数据

由于多种原因,SQL 尚未接受 IEEE 数学模型。

...

如果 IEEE 数学规则被允许
SQL,那么我们需要无限的类型转换规则以及一种方法
表示转换后的无限精确数值。人们
NULL 已经够麻烦了,所以我们不要去那里。

SQL 实现尚未确定 NULL 在特定上下文中的真正含义:

3.6.2 指数函数 (116)

问题在于,当 (x <= 0) 时,对数未定义。 一些SQL
实现返回错误消息,有些返回 NULL 和 DB2/
400;版本 3 发布 1 返回 *NEGINF(“负无穷大”的缩写)
作为其结果。


Joe Celko 引用 David McGoveran 和 CJ Date 的话:

6 个 NULL:SQL 中丢失数据 (185)

在 David McGoveran 的《Sybase 和 SQL Server 指南》一书中
CJ Date 说:“这是作者的观点,至少与 NULL 相比
目前用SQL来定义和实现,比
它们是值得并且应该避免的;他们表现得很奇怪
不一致的行为可能会成为错误和混乱的丰富根源。
(请注意,这些评论和批评适用于任何系统
支持 SQL 样式的 NULL,而不仅仅是专门针对 SQL Server。)”

NULL 作为一种毒瘾

(186/187)

在本书的其余部分,我将敦促您不要使用
它们看起来似乎是矛盾的,但事实并非如此。想一个NULL
作为药物;正确使用它,它对你有用,但滥用它,它可能会毁了你
一切。 最好的策略是尽可能避免 NULL 并使用
必要时正确地使用它们。


我在这里独特的反对意见是“正确地使用它们”,这会与
具体实施行为。

6.5.1 子查询谓词中的 NULL (191/192)

人们忘记了子查询经常隐藏与 NULL 的比较。
考虑这两个表:

...

结果将为空。这是违反直觉,但却是正确的。

(分隔符)

6.5.2 标准 SQL 解决方案(193)

SQL-92 通过添加解决了一些 3VL(三值逻辑)问题
形式的新谓词:

<搜索条件>这是[不]真实的|错误|未知

但未知本身就是问题的根源,因此 CJ Date,
在下面引用的他的书中,4.5 章中提出了建议。避免 SQL 中出现空值

  • 请勿在任何上下文中使用关键字 UNKNOWN。

阅读"ASIDE" 未知,也链接如下。

6.8 NULL 和宿主语言 (194)

但是,您应该知道当 NULL 具有
传递给主机程序。没有标准的宿主语言
定义的嵌入支持 NULL,这是另一个
避免在数据库架构中使用它们的充分理由。

(分隔符)

6.9 NULL 的设计建议 (195)

用 NOT NULL 声明所有基表是个好主意
尽可能对所有列进行约束。 NULL 让人困惑
不懂 SQL 的人,NULL 的代价是昂贵的。

反对意见:即使是熟悉 SQL 的人也会对 NULL 感到困惑,
见下文。

(195)

外键中应避免使用 NULL。 SQL 允许这种“好处
的怀疑”关系,但它可能会导致信息丢失
涉及连接的查询。例如,给定零件号代码
由订单表作为外键引用的库存,您
获取具有 NULL 的部件列表时会遇到问题。这是
强制性关系;您不能订购不存在的零件。

(分隔符)

6.9.1 避免主机程序出现 NULL (197)

您可以避免从主机程序将 NULL 放入数据库中
具有一定的编程纪律。

...

  • 确定缺失数据对编程和报告的影响:
    带有 NULL 的数字列是一个问题,因为查询
    使用聚合函数可能会提供误导性的结果。
  • (分隔符)

    (227)

    空集的 SUM() 始终为 NULL。最常见的一种
    使用此技巧时犯的编程错误是编写一个查询
    可以返回多行。如果你没有想到这一点,你可能
    将最后一个示例写为:...

    (分隔符)

    10.1.1 NULL 的来源 (242)

    记住 NULL 可能出现的位置很重要。 他们超过
    只是列中的一个可能值
    。空集上的聚合函数,
    OUTER JOIN、带有 NULL 的算术表达式和 OLAP 运算符
    全部返回 NULL。这些结构通常显示为列
    视图。

    (分隔符)

    (301)

    当您尝试转换时,发现了 NULL 的另一个问题
    IN 谓词到 EXISTS 谓词。

    (分隔符)

    16.3 ALL 谓词和极值函数 (313)

    乍一看,这两个谓词在 SQL 中并不相同,这是违反直觉的:

    ...

    但是你必须记住极值函数的规则——它们
    在返回较大值或最小值之前删除所有 NULL。这
    ALL 谓词不会删除 NULL,因此您可以在结果中获取它们。

    (分隔符)

    (315)

    但是,标准中的定义是在
    负数,这样 NULL 就可以从怀疑中受益。
    ...

    如您所见,避免 UNIQUE 中出现 NULL 是个好主意
    限制条件。

    讨论 GROUP BY:

    NULL 被视为彼此相等,并且
    形成自己的团体。然后将每个组减少为一个
    新结果表中的行替换了旧结果表。

    这意味着对于 GROUP BY 子句 NULL = NULL 不
    计算结果为 NULL,如 3VL,但计算结果为 TRUE。

    SQL标准令人困惑:

    ORDER BY 和 NULL (329)

    为 NULL 的排序键值是否被视为大于或小于
    非 NULL 值是实现定义的,但是...

    ...有些 SQL 产品可以以任何一种方式执行此操作。

    1999 年 3 月,Chris Farrar 向他的一位同事提出了一个问题
    开发人员促使他检查 SQL 标准的一部分
    我以为我明白了。克里斯发现之间存在一些差异
    规范的一般理解和实际措辞

    等等。我认为 Celko 已经足够了。

    关于 SQL NULL 的 CJ Date

    CJ Date 对于 NULL 的态度更为激进:避免在 SQL 中使用 NULL。
    事实上,他的SQL and Relational Theory: How to Write Accurate 第 4 章
    SQL 代码的标题为“NO DUPLICATES, NO NULLS”,包含子章节
    "4.4 什么是Null 错误吗?” 和“4.5 在 SQL 中避免 Null”(点击链接:
    感谢 Google 图书,您可以在线阅读某些页面)。

    Fabian Pascal 论 SQL NULL

    来自数据库管理中的实际问题 - 参考
    致思考实践者(抱歉,网上没有摘录):

    10.3 实际意义

    10.3.1 SQL NULL

    ... SQL 遭受 3VL 固有的问题以及许多问题的困扰
    怪癖、并发症、违反直觉和彻底的错误 [10, 11];
    其中包括:

    • 聚合函数(例如 SUM()、AVG())忽略 NULL(COUNT() 除外)。
    • 没有行的表上的标量表达式的计算结果错误为 NULL,而不是 0。
    • 表达式“NULL = NULL”的计算结果为 NULL,但在 SQL 中实际上是无效的;然而 ORDER BY 将 NULL 视为相等(无论它们在“常规”值之前或之后是什么,都留给 DBMS 供应商)。
    • 表达式“x IS NOT NULL”不等于“NOT(x IS NULL)”,如 2VL 中的情况。

    ...

    所有商业实现的 SQL 方言都遵循这种 3VL 方法,因此,
    他们不仅存在这些问题,而且还有具体的实施
    问题,因产品而异。

    Here I will hopefully clarify my position.

    That NULL = NULL evaluate to FALSE is wrong. Hacker and Mister correctly answered NULL.
    Here is why. Dewayne Christensen wrote to me, in a comment to Scott Ivey:

    Since it's December, let's use a
    seasonal example. I have two presents
    under the tree. Now, you tell me if I
    got two of the same thing or not.

    They can be different or they can be equal, you don't know until one open both presents. Who knows? You invited two people that don't know each other and both have done to you the same gift - rare, but not impossible §.

    So the question: are these two UNKNOWN presents the same (equal, =)? The correct answer is: UNKNOWN (i.e. NULL).

    This example was intended to demonstrate that "..(false or null, depending on your system).." is a correct answer - it is not, only NULL is correct in 3VL (or is ok for you to accept a system which gives wrong answers?)

    A correct answer to this question must emphasize this two points:

    • three-valued logic (3VL) is counterintuitive (see countless other questions on this subject on Stackoverflow and in other forum to make sure);
    • SQL-based DBMSes often do not respect even 3VL, they give wrong answers sometimes (as, the original poster assert, SQL Server do in this case).

    So I reiterate: SQL does not any good forcing one to interpret the reflexive property of equality, which state that:

    for any x, x = x §§ (in plain English: whatever the universe of discourse, a "thing" is always equal to itself).

    .. in a 3VL (TRUE, FALSE, NULL). The expectation of people would conform to 2VL (TRUE, FALSE, which even in SQL is valid for all other values), i.e. x = x always evaluate to TRUE, for any possible value of x - no exceptions.

    Note also that NULLs are valid " non-values " (as their apologists pretend them to be) which one can assign as attribute values(??) as part of relation variables. So they are acceptable values of every type (domain), not only of the type of logical expressions.

    And this was my point: NULL, as value, is a "strange beast". Without euphemism, I prefer to say: nonsense.

    I think that this formulation is much more clear and less debatable - sorry for my poor English proficiency.

    This is only one of the problems of NULLs. Better to avoid them entirely, when possible.

    § we are concerned about values here, so the fact that the two presents are always two different physical objects are not a valid objection; if you are not convinced I'm sorry, it is not this the place to explain the difference between value and "object" semantics (Relational Algebra has value semantics from the start - see Codd's information principle; I think that some SQL DBMS implementors don't even care about a common semantics).

    §§ to my knowledge, this is an axiom accepted (in a form or another, but always interpreted in a 2VL) since antiquity and that exactly because is so intuitive. 3VLs (is a family of logics in reality) is a much more recent development (but I'm not sure when was first developed).

    Side note: if someone will introduce Bottom, Unit and Option Types as attempts to justify SQL NULLs, I will be convinced only after a quite detailed examination that will shows of how SQL implementations with NULLs have a sound type system and will clarify, finally, what NULLs (these "values-not-quite-values") really are.


    In what follow I will quote some authors. Any error or omission is
    probably mine and not of the original authors.

    Joe Celko on SQL NULLs

    I see Joe Celko often cited on this forum. Apparently he is a much respected author here. So, I said to myself: "what does he wrote about SQL NULLs? How does he explain NULLs numerous problems?". One of my friend has an ebook version of Joe Celko's SQL for smarties: advanced SQL programming, 3rd edition. Let's see.

    First, the table of contents. The thing that strikes me most is the number of times that NULL is mentioned and in the most varied contexts:

    3.4 Arithmetic and NULLs 109
    3.5 Converting Values to and from NULL 110
    3.5.1 NULLIF() Function 110
    6 NULLs: Missing Data in SQL 185
    6.4 Comparing NULLs 190
    6.5 NULLs and Logic 190
    6.5.1 NULLS in Subquery Predicates 191
    6.5.2 Standard SQL Solutions 193
    6.6 Math and NULLs 193
    6.7 Functions and NULLs 193
    6.8 NULLs and Host Languages 194
    6.9 Design Advice for NULLs 195
    6.9.1 Avoiding NULLs from the Host Programs 197
    6.10 A Note on Multiple NULL Values 198
    10.1 IS NULL Predicate 241
    10.1.1 Sources of NULLs 242
    ...

    and so on. It rings "nasty special case" to me.

    I will go into some of these cases with excerpts from this book, trying to limit myself to the essential, for copyright reasons. I think these quotes fall within "fair use" doctrine and they can even stimulate to buy the book - so I hope that no one will complain (otherwise I will need to delete most of it, if not all). Furthermore, I shall refrain from reporting code snippets for the same reason. Sorry about that. Buy the book to read about datailed reasoning.

    Page numbers between parenthesis in what follow.

    NOT NULL Constraint (11)

    The most important column constraint is the NOT NULL, which forbids
    the use of NULLs in a column. Use this constraint routinely, and remove
    it only when you have good reason. It will help you avoid the
    complications of NULL values when you make queries against the data.

    It is not a value; it is a marker that holds a place where a value might go.

    Again this "value but not quite a value" nonsense. The rest seems quite sensible to me.

    (12)

    In short, NULLs cause a lot of irregular features in SQL, which we will discuss
    later. Your best bet is just to memorize the situations and the rules for NULLs
    when you cannot avoid them.

    Apropos of SQL, NULLs and infinite:

    (104) CHAPTER 3: NUMERIC DATA IN SQL

    SQL has not accepted the IEEE model for mathematics for several reasons.

    ...

    If the IEEE rules for math were allowed in
    SQL, then we would need type conversion rules for infinite and a way to
    represent an infinite exact numeric value after the conversion. People
    have enough trouble with NULLs, so let’s not go there.

    SQL implementations undecided on what NULL really means in particular contexts:

    3.6.2 Exponential Functions (116)

    The problem is that logarithms are undefined when (x <= 0). Some SQL
    implementations
    return an error message, some return a NULL and DB2/
    400; version 3 release 1 returned *NEGINF (short for “negative infinity”)
    as its result.

    Joe Celko quoting David McGoveran and C. J. Date:

    6 NULLs: Missing Data in SQL (185)

    In their book A Guide to Sybase and SQL Server, David McGoveran
    and C. J. Date said: “It is this writer’s opinion than NULLs, at least as
    currently defined and implemented in SQL, are far more trouble than
    they are worth and should be avoided; they display very strange and
    inconsistent behavior and can be a rich source of error and confusion.
    (Please note that these comments and criticisms apply to any system
    that supports SQL-style NULLs, not just to SQL Server specifically.)”

    NULLs as a drug addiction:

    (186/187)

    In the rest of this book, I will be urging you not to use
    them
    , which may seem contradictory, but it is not. Think of a NULL
    as a drug; use it properly and it works for you, but abuse it and it can ruin
    everything. Your best policy is to avoid NULLs when you can and use
    them properly when you have to.

    My unique objection here is to "use them properly", which interacts badly with
    specific implementation behaviors.

    6.5.1 NULLS in Subquery Predicates (191/192)

    People forget that a subquery often hides a comparison with a NULL.
    Consider these two tables:

    ...

    The result will be empty. This is counterintuitive, but correct.

    (separator)

    6.5.2 Standard SQL Solutions (193)

    SQL-92 solved some of the 3VL (three-valued logic) problems by adding
    a new predicate of the form:

    <search condition> IS [NOT] TRUE | FALSE | UNKNOWN

    But UNKNOWN is a source of problems in itself, so that C. J. Date,
    in his book cited below, reccomends in chapter 4.5. Avoiding Nulls in SQL:

    • Don't use the keyword UNKNOWN in any context whatsoever.

    Read "ASIDE" on UNKNOWN, also linked below.

    6.8 NULLs and Host Languages (194)

    However, you should know how NULLs are handled when they have
    to be passed to a host program. No standard host language for
    which an embedding is defined supports NULLs, which is another
    good reason to avoid using them in your database schema.

    (separator)

    6.9 Design Advice for NULLs (195)

    It is a good idea to declare all your base tables with NOT NULL
    constraints on all columns whenever possible. NULLs confuse people
    who do not know SQL, and NULLs are expensive.

    Objection: NULLs confuses even people that know SQL well,
    see below.

    (195)

    NULLs should be avoided in FOREIGN KEYs. SQL allows this “benefit
    of the doubt” relationship, but it can cause a loss of information in
    queries that involve joins. For example, given a part number code in
    Inventory that is referenced as a FOREIGN KEY by an Orders table, you
    will have problems getting a listing of the parts that have a NULL. This is
    a mandatory relationship; you cannot order a part that does not exist.

    (separator)

    6.9.1 Avoiding NULLs from the Host Programs (197)

    You can avoid putting NULLs into the database from the Host Programs
    with some programming discipline.

    ...

    1. Determine impact of missing data on programming and reporting:
      Numeric columns with NULLs are a problem, because queries
      using aggregate functions can provide misleading results.

    (separator)

    (227)

    The SUM() of an empty set is always NULL. One of the most common
    programming errors made when using this trick is to write a query that
    could return more than one row. If you did not think about it, you might
    have written the last example as: ...

    (separator)

    10.1.1 Sources of NULLs (242)

    It is important to remember where NULLs can occur. They are more than
    just a possible value in a column
    . Aggregate functions on empty sets,
    OUTER JOINs, arithmetic expressions with NULLs, and OLAP operators
    all return NULLs. These constructs often show up as columns in
    VIEWs.

    (separator)

    (301)

    Another problem with NULLs is found when you attempt to convert
    IN predicates to EXISTS predicates.

    (separator)

    16.3 The ALL Predicate and Extrema Functions (313)

    It is counterintuitive at first that these two predicates are not the same in SQL:

    ...

    But you have to remember the rules for the extrema functions—they
    drop out all the NULLs before returning the greater or least values. The
    ALL predicate does not drop NULLs, so you can get them in the results.

    (separator)

    (315)

    However, the definition in the standard is worded in the
    negative, so that NULLs get the benefit of the doubt.
    ...

    As you can see, it is a good idea to avoid NULLs in UNIQUE
    constraints.

    Discussing GROUP BY:

    NULLs are treated as if they were all equal to each other, and
    form their own group. Each group is then reduced to a single
    row in a new result table that replaces the old one.

    This means that for GROUP BY clause NULL = NULL does not
    evaluate to NULL, as in 3VL, but it evaluate to TRUE.

    SQL standard is confusing:

    The ORDER BY and NULLs (329)

    Whether a sort key value that is NULL is considered greater or less than a
    non-NULL value is implementation-defined, but...

    ... There are SQL products that do it either way.

    In March 1999, Chris Farrar brought up a question from one of his
    developers that caused him to examine a part of the SQL Standard that
    I thought I understood
    . Chris found some differences between the
    general understanding and the actual wording of the specification
    .

    And so on. I think is enough by Celko.

    C. J. Date on SQL NULLs

    C. J. Date is more radical about NULLs: avoid NULLs in SQL, period.
    In fact, chapter 4 of his SQL and Relational Theory: How to Write Accurate
    SQL Code
    is titled "NO DUPLICATES, NO NULLS", with subchapters
    "4.4 What's Wrong with Nulls?" and "4.5 Avoiding Nulls in SQL" (follow the link:
    thanks to Google Books, you can read some pages on-line).

    Fabian Pascal on SQL NULLs

    From its Practical Issues in Database Management - A Reference
    for the Thinking Practitioner
    (no excerpts on-line, sorry):

    10.3 Pratical Implications

    10.3.1 SQL NULLs

    ... SQL suffers from the problems inherent in 3VL as well as from many
    quirks, complications, counterintuitiveness, and outright errors [10, 11];
    among them are the following:

    • Aggregate functions (e.g., SUM(), AVG()) ignore NULLs (except for COUNT()).
    • A scalar expression on a table without rows evaluates incorrectly to NULL, instead of 0.
    • The expression "NULL = NULL" evaluates to NULL, but is actually invalid in SQL; yet ORDER BY treats NULLs as equal (whatever they precede or follow "regular" values is left to DBMS vendor).
    • The expression "x IS NOT NULL" is not equal to "NOT(x IS NULL)", as is the case in 2VL.

    ...

    All commercially implemented SQL dialects follow this 3VL approach, and, thus,
    not only do they exibits these problems, but they also have spefic implementation
    problems, which vary across products
    .

    桃扇骨 2024-08-21 01:36:34

    这里的答案似乎都来自于CS的角度,所以我想从开发者的角度添加一个。

    对于开发人员来说 NULL 非常有用。这里的答案说NULL意味着未知,也许在CS理论中这是真的,不记得了,已经有一段时间了。但在实际开发中,至少根据我的经验,这种情况发生的概率约为 1%。另外 99% 用于该值并非未知但已知不存在的情况。

    例如:

    • 使用软删除时,deletedAt = NULL并不意味着我们不知道它何时被删除,而是意味着它没有被删除

    • Client.LastPurchase,对于新客户。这不是未知的,已知他还没有购买。

    • 当使用带有的ORM时,每个 层次结构映射,有些值只是没有映射到某些类。

    • 映射树结构时,根通常会有Parent = NULL

    • 还有更多...

    我确信大多数开发人员在某个时候都会写过 WHERE value = NULL
    没有得到任何结果,这就是他们了解 IS NULL 语法的方式。只要看看这个问题和相关问题有多少票即可。

    SQL 数据库是一种工具,应该以最容易让用户理解的方式进行设计。

    The answers here all seem to come from a CS perspective so I want to add one from a developer perspective.

    For a developer NULL is very useful. The answers here say NULL means unknown, and maybe in CS theory that's true, don't remember, it's been a while. In actual development though, at least in my experience, that happens about 1% of the time. The other 99% it is used for cases where the value is not UNKNOWN but it is KNOWN TO BE ABSENT.

    For example:

    • When using soft deletes, deletedAt = NULL doesn't mean we don't know when it was deleted, it means it wasn't deleted.

    • Client.LastPurchase, for a new client. It is not unknown, it is known that he hasn't made a purchase yet.

    • When using an ORM with a Table per Class Hierarchy mapping, some values are just not mapped for certain classes.

    • When mapping a tree structure a root will usually have Parent = NULL

    • And many more...

    I'm sure most developers at some point wrote WHERE value = NULL,
    didn't get any results, and that's how they learned about IS NULL syntax. Just look how many votes this question and the linked ones have.

    SQL Databases are a tool, and they should be designed the way which is easiest for their users to understand.

    骑趴 2024-08-21 01:36:34

    仅仅因为您不知道两件事是什么,并不意味着它们是相等的。如果当您想到 NULL 时,您会想到“NULL”(字符串),那么您可能需要不同的相等性测试,例如 Postgresql 的 IS DISTINCT FROM AND IS NOT DISTINCT FROM

    来自 PostgreSQL 文档“比较函数和运算符”

    表达式表达式不同

    表达式表达式不同

    对于非空输入,IS DISTINCT FROM<> 运算符相同。但是,如果两个输入均为 null,则返回 false,如果只有一个输入为 null,则返回 true。同样,对于非 null 输入,IS NOT DISTINCT FROM= 相同,但当两个输入都为 null 时,它返回 true;当只有一个输入为 null 时,它返回 false。因此,这些构造实际上就像 null 是一个正常的数据值,而不是“未知”。

    Just because you don't know what two things are, does not mean they're equal. If when you think of NULL you think of “NULL” (string) then you probably want a different test of equality like Postgresql's IS DISTINCT FROM AND IS NOT DISTINCT FROM

    From the PostgreSQL docs on "Comparison Functions and Operators"

    expression IS DISTINCT FROM expression

    expression IS NOT DISTINCT FROM expression

    For non-null inputs, IS DISTINCT FROM is the same as the <> operator. However, if both inputs are null it returns false, and if only one input is null it returns true. Similarly, IS NOT DISTINCT FROM is identical to = for non-null inputs, but it returns true when both inputs are null, and false when only one input is null. Thus, these constructs effectively act as though null were a normal data value, rather than "unknown".

    暮光沉寂 2024-08-21 01:36:34

    也许这取决于情况,但我认为 NULL=NULL 的计算结果为 NULL 就像大多数以 NULL 作为操作数的操作一样。

    Maybe it depends, but I thought NULL=NULL evaluates to NULL like most operations with NULL as an operand.

    哎呦我呸! 2024-08-21 01:36:34

    technet 有一个很好的解释了解空值的工作原理。

    空意味着未知。

    因此,布尔表达式

    value=null 的

    计算结果不是 false,而是 null,但如果这是 where 子句的最终结果,则不会返回任何内容。这是一种实用的方法,因为返回 null 很难想象。

    理解以下内容很有趣并且非常重要:

    如果在查询中我们有

    where (value=@param Or @param is null) And id=@anotherParam
    

    value

    • =1
    • @param 为 null
    • id=123
    • @anotherParam=123

    那么

    “value=@param”的计算结果为 null< br>
    “@param is null”的计算结果为 true
    "id=@anotherParam" 计算结果为 true

    所以要计算的表达式变为

    (null Or true) And true

    我们可能会想,这里“null Or true”将计算为 null,因此整个表达式变为 null,并且行将不会被返回。

    事实并非如此。为什么?

    因为“null Or true”的计算结果为 true,这是非常合乎逻辑的,因为如果 Or 运算符的一个操作数为 true,则无论另一个操作数的值如何,该操作都将返回 true。因此,另一个操作数未知(空)并不重要。

    所以我们最终得到 true=true 并且该行将被返回。

    注意:使用与“null Or true”计算结果为 true 相同的清晰逻辑,“null And true”计算结果为 null。

    更新:
    好吧,为了使它完整,我也想在这里添加其余的内容,这与上面的内容相比非常有趣。

    “null Or false”计算结果为 null,“null And false”计算结果为 false。 :)

    逻辑当然还是像以前一样不言而喻。

    At technet there is a good explanation for how null values work.

    Null means unknown.

    Therefore the Boolean expression

    value=null

    does not evaluate to false, it evaluates to null, but if that is the final result of a where clause, then nothing is returned. That is a practical way to do it, since returning null would be difficult to conceive.

    It is interesting and very important to understand the following:

    If in a query we have

    where (value=@param Or @param is null) And id=@anotherParam
    

    and

    • value=1
    • @param is null
    • id=123
    • @anotherParam=123

    then

    "value=@param" evaluates to null
    "@param is null" evaluates to true
    "id=@anotherParam" evaluates to true

    So the expression to be evaluated becomes

    (null Or true) And true

    We might be tempted to think that here "null Or true" will be evaluated to null and thus the whole expression becomes null and the row will not be returned.

    This is not so. Why?

    Because "null Or true" evaluates to true, which is very logical, since if one operand is true with the Or-operator, then no matter the value of the other operand, the operation will return true. Thus it does not matter that the other operand is unknown (null).

    So we finally have true=true and thus the row will be returned.

    Note: with the same crystal clear logic that "null Or true" evaluates to true, "null And true" evaluates to null.

    Update:
    Ok, just to make it complete I want to add the rest here too which turns out quite fun in relation to the above.

    "null Or false" evaluates to null, "null And false" evaluates to false. :)

    The logic is of course still as self-evident as before.

    情丝乱 2024-08-21 01:36:34

    MSDN 有一篇关于空值和它们产生的三种状态逻辑。

    简而言之,SQL92 规范将 NULL 定义为未知,并且在以下运算符中使用 NULL 会导致外行人意外的结果:

    = operator NULL   true   false 
    NULL       NULL   NULL   NULL
    true       NULL   true   false
    false      NULL   false  true
    
    and op     NULL   true   false 
    NULL       NULL   NULL   false
    true       NULL   true   false
    false      false  false  false
    
    or op      NULL   true   false 
    NULL       NULL   true   NULL
    true       true   true   true
    false      NULL   true   false
    

    MSDN has a nice descriptive article on nulls and the three state logic that they engender.

    In short, the SQL92 spec defines NULL as unknown, and NULL used in the following operators causes unexpected results for the uninitiated:

    = operator NULL   true   false 
    NULL       NULL   NULL   NULL
    true       NULL   true   false
    false      NULL   false  true
    
    and op     NULL   true   false 
    NULL       NULL   NULL   false
    true       NULL   true   false
    false      false  false  false
    
    or op      NULL   true   false 
    NULL       NULL   true   NULL
    true       true   true   true
    false      NULL   true   false
    
    此岸叶落 2024-08-21 01:36:34

    至少可以说,NULL 的概念是有问题的。 Codd 在上下文中引入了关系模型和 NULL 的概念(并继续提出了不止一种 NULL!)但是,自 Codd 的原始著作以来,关系理论已经发展:他的一些建议已被删除(例如主键)还有一些从未流行起来(例如 theta 运算符)。在现代关系理论(真正的关系理论,我应该强调)中,NULL 根本不存在。参见第三宣言。 http://www.thethirdmanifesto.com/

    SQL 语言存在向后兼容性问题。 NULL 进入了 SQL,而我们却被它困住了。可以说,SQL 中 NULL 的实现是有缺陷的(SQL Server 的实现由于它的 ANSI_NULLS 选项而使事情变得更加复杂)。

    我建议避免在基表中使用可空列。


    尽管也许我不应该受到诱惑,但我只是想对 NULL 在 SQL 中的工作方式进行自己的更正:

    NULL = NULL计算结果为UNKNOWN

    UNKNOWN 是一个逻辑值。

    NULL 是一个数据值。

    这很容易证明,例如

    SELECT NULL = NULL

    在 SQL Server 中正确生成错误。如果结果是一个数据值,那么我们会期望看到 NULL,正如这里的一些答案(错误地)建议的那样。

    SQL DML 和 SQL DDL 中对逻辑值 UNKNOWN 的处理方式分别不同。

    在 SQL DML 中,UNKNOWN 会导致从结果集中删除行。

    例如:

    CREATE TABLE MyTable
    (
     key_col INTEGER NOT NULL UNIQUE, 
     data_col INTEGER
     CHECK (data_col = 55)
    );
    
    INSERT INTO MyTable (key_col, data_col)
       VALUES (1, NULL);
    

    即使 CHECK 条件解析为 NULL = NULL,该行的 INSERT 也会成功。这是在 SQL-92(“ANSI”)标准中定义的:

    11.6 表约束定义

    3)

    如果表约束是检查
    约束定义,则令 SC 为
    立即搜索条件
    包含在检查约束中
    定义并令 T 为表名
    包含在相应的表中
    约束描述符;桌子
    不满足约束条件,如果并且
    仅当

    存在(从 T 中选择 *,其中不存在)
    (SC))

    是真的。

    按照逻辑再仔细阅读一遍。

    用简单的英语来说,我们上面的新行被赋予了“未知的好处”,即“未知”并被允许通过。

    在 SQL DML 中,WHERE 子句的规则更容易遵循:

    搜索条件适用于
    T 的每一行。 where 的结果
    子句是 T 的那些行的表
    其搜索结果
    条件为真。

    简而言之,计算结果为 UNKNOWN 的行将从结果集中删除。

    The concept of NULL is questionable, to say the least. Codd introduced the relational model and the concept of NULL in context (and went on to propose more than one kind of NULL!) However, relational theory has evolved since Codd's original writings: some of his proposals have since been dropped (e.g. primary key) and others never caught on (e.g. theta operators). In modern relational theory (truly relational theory, I should stress) NULL simply does not exist. See The Third Manifesto. http://www.thethirdmanifesto.com/

    The SQL language suffers the problem of backwards compatibility. NULL found its way into SQL and we are stuck with it. Arguably, the implementation of NULL in SQL is flawed (SQL Server's implementation makes things even more complicated due to its ANSI_NULLS option).

    I recommend avoiding the use of NULLable columns in base tables.


    Although perhaps I shouldn't be tempted, I just wanted to assert a corrections of my own about how NULL works in SQL:

    NULL = NULL evaluates to UNKNOWN.

    UNKNOWN is a logical value.

    NULL is a data value.

    This is easy to prove e.g.

    SELECT NULL = NULL

    correctly generates an error in SQL Server. If the result was a data value then we would expect to see NULL, as some answers here (wrongly) suggest we would.

    The logical value UNKNOWN is treated differently in SQL DML and SQL DDL respectively.

    In SQL DML, UNKNOWN causes rows to be removed from the resultset.

    For example:

    CREATE TABLE MyTable
    (
     key_col INTEGER NOT NULL UNIQUE, 
     data_col INTEGER
     CHECK (data_col = 55)
    );
    
    INSERT INTO MyTable (key_col, data_col)
       VALUES (1, NULL);
    

    The INSERT succeeds for this row, even though the CHECK condition resolves to NULL = NULL. This is due defined in the SQL-92 ("ANSI") Standard:

    11.6 table constraint definition

    3)

    If the table constraint is a check
    constraint definition, then let SC be
    the search condition immediately
    contained in the check constraint
    definition and let T be the table name
    included in the corresponding table
    constraint descriptor; the table
    constraint is not satisfied if and
    only if

    EXISTS ( SELECT * FROM T WHERE NOT
    ( SC ) )

    is true.

    Read that again carefully, following the logic.

    In plain English, our new row above is given the 'benefit of the doubt' about being UNKNOWN and allowed to pass.

    In SQL DML, the rule for the WHERE clause is much easier to follow:

    The search condition is applied to
    each row of T. The result of the where
    clause is a table of those rows of T
    for which the result of the search
    condition is true.

    In plain English, rows that evaluate to UNKNOWN are removed from the resultset.

    爱的那么颓废 2024-08-21 01:36:34

    因为 NULL 表示“未知值”,并且两个未知值不能相等。

    因此,如果按照我们的逻辑 NULL N°1 等于 NULL N°2,那么我们必须以某种方式告诉我们:

    SELECT 1
    WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)
    

    已知值 -1 N°1 等于 -1 N°2

    Because NULL means 'unknown value' and two unknown values cannot be equal.

    So, if to our logic NULL N°1 is equal to NULL N°2, then we have to tell that somehow:

    SELECT 1
    WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)
    

    where known value -1 N°1 is equal to -1 N°2

    梦忆晨望 2024-08-21 01:36:34

    有两种明智的方法可以处理 WHERE 子句中的 NULL = NULL 比较,它们归结为“NULL 是什么意思?”一种方式假设 NULL 表示“未知”,另一种方式假设 NULL 表示“数据不存在”。 SQL 选择了第三种方式,但这是完全错误的。

    “NULL 表示未知”解决方案: 抛出错误。

    Unknown = 未知应计算为 3VL null。但 WHERE 子句的输出是 2VL:您要么返回该行,要么不返回。这就像被要求除以零并返回一个数字:没有正确的响应。因此,您会抛出一个错误,并强制程序员显式处理这种情况。

    “NULL 表示没有数据”解决方案: 返回行。

    无数据 = 没有数据应评估为 true。如果我比较两个人,他们有相同的名字和相同的姓氏,并且都没有中间名,那么说“这些人有相同的名字”是正确的。

    SQL 解决方案: 不要返回行。

    总是错误的。如果 NULL 表示“未知”,那么您不知道是否应该返回该行,并且您不应该尝试猜测。如果 NULL 表示“没有数据”,那么您应该返回该行。无论哪种方式,默默地删除该行都是不正确的,并且会导致问题。这是两全其美的最糟糕的情况。

    抛开理论,从实际角度来说,我同意 AlexDev 的观点:我几乎从未遇到过“返回行”不是所需结果的情况。然而,“几乎从不”并不是“从不”,而且 SQL 数据库通常充当大型重要系统的支柱,因此我可以看到严格并抛出错误的公平案例。

    我看不到的是默默地将 3VL null 强制为 2VL false 的情况。像大多数无声类型的强制一样,它就像一只疯狂的黄鼠狼等待着在你的系统中被释放,当黄鼠狼最终跳出来咬某人时,你就会有一个快乐的恶魔追踪它回到它的巢穴。

    There are two sensible ways to handle NULL = NULL comparisons in a WHERE clause, and they boil down to "What do you mean by NULL?" One way assumes NULL means "unknown," and the other assumes NULL means "data does not exist." SQL has chosen a third way which is wrong all around.

    The "NULL means unknown" solution: Throw an error.

    Unknown = unknown should evaluate to 3VL null. But the output of a WHERE clause is 2VL: You either return the row or you don't. It's like being asked to divide by zero and return a number: There is no correct response. So you throw an error instead, and force the programmer to explicitly handle this situation.

    The "NULL means no data" solution: Return the row.

    No data = no data should evaluate to true. If I'm comparing two people, and they have the same first name, and the same last name, and neither has a middle name, then it is correct to say "These people have the same name."

    The SQL solution: Don't return the row.

    This is always wrong. If NULL means "unknown," then you don't know if the row should be returned or not, and you should not try to guess. If NULL means "no data," then you should return the row. Either way, silently removing the row is incorrect and will cause problems. It's the worst of both worlds.

    Setting aside theory and speaking in practical terms, I'm with AlexDev: I have almost never encountered a case where "return the row" was not the desired result. However, "almost never" is not "never," and SQL databases often serve as the backbones of big important systems, so I can see a fair case for being rigorous and throwing an error.

    What I cannot see is a case for silently coercing 3VL null into 2VL false. Like most silent type coercions, it's a rabid weasel waiting to be set loose in your system, and when the weasel finally jumps out and bites someone, you'll have the merry devil of a time tracking it back to its nest.

    蘸点软妹酱 2024-08-21 01:36:34

    NULL 不等于任何东西,甚至不等于它本身。我个人理解 NULL 行为的解决方案是尽可能避免使用它:)。

    NULL isn't equal to anything, not even itself. My personal solution to understanding the behavior of NULL is to avoid using it as much as possible :).

    相思碎 2024-08-21 01:36:34

    问题:
    一个未知数是否等于另一个未知数?
    (空=空)
    这个问题是没人能回答的,所以它默认为 true 或 false,具体取决于您的 ansi_nulls 设置。

    然而问题是:
    这个未知变量是未知的吗?
    这个问题完全不同,可以用 true 来回答。

    nullVariable = null 正在比较值
    nullVariable is null 正在比较变量的状态

    The question:
    Does one unknown equal another unknown?
    (NULL = NULL)
    That question is something no one can answer so it defaults to true or false depending on your ansi_nulls setting.

    However the question:
    Is this unknown variable unknown?
    This question is quite different and can be answered with true.

    nullVariable = null is comparing the values
    nullVariable is null is comparing the state of the variable

    挽清梦 2024-08-21 01:36:34

    混乱源自使用 NULL 所产生的间接(抽象)级别

    回到“圣诞树下有什么”的类比,“未知”描述了关于盒子 A 中的内容的知识状态。

    因此,如果你不知道盒子 A 中有什么,你就说它是“未知”,但是 这并不意味着“未知”在盒子内。盒子里有一些未知的东西,可能是某种物体,或者盒子里可能什么也没有。

    同样,如果您不知道方框 B 中的内容,您可以将您对内容的了解状态标记为“未知”。

    因此,关键在于:您对方框 A 的了解程度等于您对方框 B 的了解程度。 (在这两种情况下,您的知识状态都是“未知”或“我不知道盒子里有什么”。)但是盒子里的内容可能相同,也可能不同。

    回到 SQL,理想情况下,您应该只有在知道值是什么时才能比较它们。 不幸的是,描述缺乏知识的标签存储在单元格本身中,因此我们很想将其用作值。但我们不应该将其用作值,因为这会导致“当我们不知道盒子 A 中的内容和/或我们不知道盒子 B 中的内容时,盒子 A 的内容等于盒子 B 的内容。
    (从逻辑上讲,“如果我不知道盒子 A 里有什么,如果我不知道盒子 B 里有什么,那么盒子 A 里的东西 = 盒子 B 里有什么”的含义是错误的。)

    是的,死马。

    The confusion arises from the level of indirection (abstraction) that comes about from using NULL.

    Going back to the "what's under the Christmas tree" analogy, "Unknown" describes the state of knowledge about what is in Box A.

    So if you don't know what's in Box A, you say it's "Unknown", but that doesn't mean that "Unknown" is inside the box. Something other than unknown is in the box, possibly some kind of object, or possibly nothing is in the box.

    Similarly, if you don't know what's in Box B, you can label your state of knowledge about the contents as being "Unknown".

    So here's the kicker: Your state of knowledge about Box A is equal to your state of knowledge about Box B. (Your state of knowledge in both cases is "Unknown" or "I don't know what's in the Box".) But the contents of the boxes may or may not be equal.

    Going back to SQL, ideally you should only be able to compare values when you know what they are. Unfortunately, the label that describes a lack of knowledge is stored in the cell itself, so we're tempted to use it as a value. But we should not use that as a value, because it would lead to "the content of Box A equals the content of Box B when we don't know what's in Box A and/or we don't know what's in Box B.
    (Logically, the implication "if I don't know what's in Box A and if I don't know what's in Box B, then what's in Box A = What's in Box B" is false.)

    Yay, Dead Horse.

    凉风有信 2024-08-21 01:36:34

    null 在 SQL 中是未知的,因此我们不能期望两个未知数相同。

    但是,您可以通过将 ANSI_NULLS 设置为 Off(默认情况下为 On)来获得该行为
    您将能够对空值使用 = 运算符

    SET ANSI_NULLS off
    if null=null
    print 1
    else 
    print 2
    set ansi_nulls on
    if null=null
    print 1
    else 
    print 2
    

    null is unknown in sql so we cant expect two unknowns to be same.

    However you can get that behavior by setting ANSI_NULLS to Off(its On by Default)
    You will be able to use = operator for nulls

    SET ANSI_NULLS off
    if null=null
    print 1
    else 
    print 2
    set ansi_nulls on
    if null=null
    print 1
    else 
    print 2
    
    对不⑦ 2024-08-21 01:36:34

    您为政府工作,登记有关公民的信息。这包括该国每个人的国民身份证。大约40年前,一个孩子被留在教堂门口,没有人知道他们的父母是谁。此人的父亲 ID 为 NULL。这样的人有两个。计算与至少一个其他人(兄弟姐妹)共享同一父亲 ID 的人数。这两个你也算吗?

    答案是否定的,你不知道,因为我们不知道他们是否是兄弟姐妹。

    假设你没有 NULL 选项,而是使用一些预先确定的值来表示“未知”,可能是空字符串或数字 0 或 * 字符等。那么你会在您的查询中包含 * = *、0 = 0 和“” = “”等。这不是您想要的(如上面的示例所示),而且您可能经常忘记这些情况(上面的示例是一个超出日常思维的清晰边缘案例),那么您需要语言来记住 NULL = NULL 不是真的。

    需要是发明之母。

    You work for the government registering information about citizens. This includes the national ID for every person in the country. A child was left at the door of a church some 40 years ago, nobody knows who their parents are. This person's father ID is NULL. Two such people exist. Count people who share the same father ID with at least one other person (people who are siblings). Do you count those two too?

    The answer is no, you don’t, because we don’t know if they are siblings or not.

    Suppose you don’t have a NULL option, and instead use some pre-determined value to represent “the unknown”, perhaps an empty string or the number 0 or a * character, etc. Then you would have in your queries that * = *, 0 = 0, and “” = “”, etc. This is not what you want (as per the example above), and as you might often forget about these cases (the example above is a clear fringe case outside ordinary everyday thinking), then you need the language to remember for you that NULL = NULL is not true.

    Necessity is the mother of invention.

    初相遇 2024-08-21 01:36:34

    再次引用圣诞节的比喻:

    在 SQL 中,NULL 基本上意味着“封闭的盒子”(未知)。因此,比较两个封闭框的结果也将是未知的(空)。

    我知道,对于开发人员来说,这是违反直觉的,因为在编程语言中,NULL 通常意味着“空盒子”(已知)。比较两个空盒子自然会得到 true / equal。

    这就是 JavaScript 区分 nullundefined 的原因。

    To quote the Christmas analogy again:

    In SQL, NULL basically means "closed box" (unknown). So, the result of comparing two closed boxes will also be unknown (null).

    I understand, for a developer, this is counter-intuitive, because in programming languages, often NULL rather means "empty box" (known). And comparing two empty boxes will naturally yield true / equal.

    This is why JavaScript for example distinguishes between null and undefined.

    傾旎 2024-08-21 01:36:34

    只是对其他精彩答案的补充:

    AND: The result of true and unknown is unknown, false and unknown is false,
    while unknown and unknown is unknown.
    
    OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.
    
    NOT: The result of not unknown is unknown
    

    Just an addition to other wonderful answers:

    AND: The result of true and unknown is unknown, false and unknown is false,
    while unknown and unknown is unknown.
    
    OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.
    
    NOT: The result of not unknown is unknown
    
    幻梦 2024-08-21 01:36:34

    如果您正在寻找对两个 NULL 返回 true 的表达式,您可以使用:

    SELECT 1 
    WHERE EXISTS (
        SELECT NULL
        INTERSECT
        SELECT NULL
    )
    

    如果您想要将数据从一个表复制到另一个表,这会很有帮助。

    If you are looking for an expression returning true for two NULLs you can use:

    SELECT 1 
    WHERE EXISTS (
        SELECT NULL
        INTERSECT
        SELECT NULL
    )
    

    It is helpful if you want to replicate data from one table to another.

    清眉祭 2024-08-21 01:36:34

    例如,在 case 语句中的when子句中,相等性测试可以从 改为

    XYZ = NULL 
    

    XYZ IS NULL
    

    如果我想将空格和空字符串视为等于 NULL,我也经常使用相等性测试,例如:

    (NULLIF(ltrim( XYZ ),'') IS NULL)
    

    The equality test, for example, in a case statement when clause, can be changed from

    XYZ = NULL 
    

    to

    XYZ IS NULL
    

    If I want to treat blanks and empty string as equal to NULL I often also use an equality test like:

    (NULLIF(ltrim( XYZ ),'') IS NULL)
    
    输什么也不输骨气 2024-08-21 01:36:34

    Null 不等于任何东西,包括它自己
    测试对象是否为 null 的最佳方法是检查该对象是否等于自身,因为 null 是唯一不等于自身的对象

    const obj = null

    console.log(obj==obj) //false, then it's null

    查看这篇文章

    Null isn't equal to anything including itself
    Best way to test if an object is null is to check whether the object equals itself since null is the only object not equal to itself

    const obj = null

    console.log(obj==obj) //false, then it's null

    Check this article

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文