gpt4 book ai didi

sql-server - SQL Server : Why does comparison null=value return true for NOT IN?

转载 作者:行者123 更新时间:2023-12-02 14:30:10 25 4
gpt4 key购买 nike

为什么value的比较至null返回 false,除非使用 NOT IN ,哪里返回 true?

<小时/>

给定一个查询来查找所有拥有帖子的 stackoverflow 用户:

SELECT * FROM Users
WHERE UserID IN (SELECT UserID FROM Posts)

这按预期工作;我得到了所有拥有帖子的用户的列表。

现在查询逆;查找所有没有发布帖子的 stackoverflow 用户:

SELECT * FROM Users
WHERE UserID NOT IN (SELECT UserID FROM Posts)

这不会返回任何记录,这是不正确的。

给定假设数据1

Users              Posts
================ ===============================
UserID Username PostID UserID Subject
------ -------- ------- ------ ----------------
1 atkins 1 1 Welcome to stack ov...
2 joels 2 2 Welcome all!
... ... ... ...
399573 gt6989b ... ...
... ... ... ...
10592 null (deleted by nsl&fbi...
... ...

并假设 NULL 规则:

  • NULL = NULL评估为未知
  • NULL <> NULL评估为未知
  • value = NULL评估未知

如果我们查看第二个查询,我们感兴趣的是查找在 Posts.UserID 列中找到 Users.UserID 的所有行。我会按照逻辑进行如下操作:

检查用户 ID 1

  • 1 = 1返回真。因此我们得出结论,该用户有一些帖子,并且不将它们包含在输出列表中

现在检查用户 ID 2:

  • 2 = 1返回 false,所以我们继续寻找
  • 2 = 2返回true,因此我们得出结论该用户有一些帖子,并且不将它们包含在输出列表中

现在检查用户ID 399573

  • 399573 = 1返回 false,所以我们继续寻找
  • 399573 = 2返回 false,所以我们继续寻找
  • ...
  • 399573 = null返回未知,所以我们继续寻找
  • ...

我们没有找到 UserID 399573 的帖子,因此我们会将他包含在输出列表中。

但 SQL Server 不这样做。如果你的in中有一个NULL列表,然后突然找到一个匹配项。 它突然找到了匹配项。突然399573 = null评估结果为真。

为什么value的比较至null返回未知,除非返回 true?

编辑:我知道我可以通过专门排除空值来解决这个 无意义 行为:

SELECT * FROM Users
WHERE UserID NOT IN (
SELECT UserID FROM Posts
WHERE UserID IS NOT NULL)

但我不应该这样做,据我所知,没有它 bool 逻辑应该没问题 - 因此我的问题。

脚注

  • 1 假设数据;如果您不喜欢,请补足羽绒服。
  • celko 现在有了自己的标签

最佳答案

常见问题,预设答案:

NOT IN 子句的行为可能会令人困惑,因此需要一些解释。考虑以下查询:

SELECT LastName, FirstName FROM Person.Contact WHERE LastName NOT IN('Hedlund', 'Holloway', NULL)

尽管 AdventureWorks.Person.Contact 中有一千多个不同的姓氏,但查询不会返回任何内容。对于初学者数据库程序员来说,这可能看起来违反直觉,但实际上是完全有道理的。该解释由几个简单的步骤组成。首先,考虑以下两个查询,它们显然是等价的:

SELECT LastName, FirstName FROM Person.Contact

WHERE LastName IN('Hedlund', 'Holloway', NULL)



SELECT LastName, FirstName FROM Person.Contact

WHERE LastName='Hedlund' OR LastName='Holloway' OR LastName=NULL

请注意,两个查询都返回预期结果。现在,让我们回顾一下德摩根定理,该定理指出:

not (P and Q) = (not P) or (not Q)

not (P or Q) = (not P) and (not Q)

我正在从维基百科 (http://en.wikipedia.org/wiki/De_Morgan_duality) 剪切和粘贴。将德摩根定理应用于此查询,可以得出这两个查询也是等价的:

SELECT LastName, FirstName FROM Person.Contact WHERE LastName NOT IN('Hedlund', 'Holloway', NULL)



SELECT LastName, FirstName FROM Person.Contact

WHERE LastName<>'Hedlund' AND LastName<>'Holloway' AND LastName<>NULL

最后一个 LastName<>NULL 永远不可能为 true

关于sql-server - SQL Server : Why does comparison null=value return true for NOT IN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3924694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com