MySQL的'NOT IN'在没有匹配项时返回空结果
MySQL的'NOT IN'在没有匹配项时返回空结果
我的表是:
树表: +----+------+ | id | p_id | +----+------+ | 1 | null | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 2 | +----+------+
如果我执行以下查询:
SELECT id FROM Tree WHERE id IN (SELECT p_id FROM Tree)
我得到了预期的答案:
+----+ | id | +----+ | 1 | | 2 | +----+
然而,如果我执行以下查询:
SELECT id FROM Tree WHERE id NOT IN (SELECT p_id FROM Tree)
我得到了一个空结果:
+----+ | id | +----+ +----+
而不是预期的3, 4, 5。据我理解,NOT IN
应该给出由IN
得到的互补集(排除NULL
)?
我对SQL还不熟悉,如果我遗漏了一些基础知识,对不起。
MySQL 'NOT IN' returns empty result even when there is no match的问题出现的原因是IN操作符不考虑NULL值。解决这个问题的方法是使用NOT EXISTS操作符,它可以考虑NULL值。下面是一个示例查询:
SELECT id FROM Tree WHERE NOT EXISTS (SELECT 1 FROM Tree t1 WHERE t1.p_id = Tree.id);
你可以在以下链接中查看一个示例:[https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=fff39bf4a29193a8eb9644b9c126771b](https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=fff39bf4a29193a8eb9644b9c126771b)
MySQL中的'NOT IN'运算符在没有匹配项时返回空结果的原因是,Null表示缺失但存在的数据。因此,当引擎在集合中找不到明确的匹配项时,它无法确定一行是否不在集合中。因此,在存在null值的情况下,'NOT IN'将不会产生任何行。
然而,您可以使用反连接(anti-join)来获得所需的结果。例如:
select a.id from tree a left join tree b on b.p_id = a.id where b.p_id is null
另外,您还可以使用'NOT EXISTS'。引擎可以确定一个值是否在列表中,但如果列表包含null值,则无法确定某个值是否不在列表中(因为something = null或something = something可判定为真,而something = null或something = something_else不可判定,因此是未知的(null),not(unknown)也是未知的)。