为什么 NOT IN 包含 NULL 的集合总是返回 FALSE/NULL?

new*_*der 21 postgresql null query informix

我有一个查询(针对 Postgres 和 Informix),其中NOT IN包含一个子查询,该子查询在某些情况下返回NULL值,导致该子句(以及整个查询)无法返回任何内容。

理解这一点的最佳方式是什么?我认为NULL没有价值的东西,因此不希望查询失败,但显然这不是考虑NULL.

gbn*_*gbn 31

布尔逻辑 - 或三值逻辑

  • IN 是一系列 OR 条件的简写
  • x NOT IN (1, 2, NULL) 是相同的 NOT (x = 1 OR x = 2 OR x = NULL)
  • ... 是相同的 x <> 1 AND x <> 2 AND x <> NULL
  • ...与true AND true AND unknown**相同
  • ... = unknown**
  • ...这与false本例几乎相同,因为它不会通过WHERE条件 **

现在,这就是为什么人们使用EXISTS+NOT EXISTS而不是IN+ 的原因NOT IN。另请参阅与索引相关的 NOT 逻辑的使用以获取更多信息

** 注意:unknown与条件false中的表达式末尾相同WHERE
在评估表达式时,它是未知的,
请参阅下面的@kgrittn 评论以了解原因

  • 即使有澄清,它在技术上也是错误的,并且可能会烧伤某人。例如,如果你认为 `x &lt;&gt; NULL` 解析为 `FALSE`,你会期望 `NOT (x &lt;&gt; NULL)` 评估为 `TRUE`,但事实并非如此。*两者*评估为“未知”。诀窍是仅当“WHERE”子句(如果存在)的计算结果为“TRUE”时才选择一行——如果该子句的计算结果为“FALSE”或“UNKNOWN”,则省略一行。这种行为(一般来说,特别是对于“NOT IN”谓词)是 SQL 标准规定的。 (10认同)