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


21

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

理解这一点的最好方法是什么?我认为NULL这是没有价值的事情,因此并不期望查询会失败,但是显然,这不是正确的思考方式NULL

Answers:


29

布尔逻辑-或三值逻辑

  • 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。另请参阅有关指标的使用不是一个逻辑更多

**注意:unknown与条件false表达式中的末尾相同WHERE
在对表达式求值时,它是未知的。
有关原因,请参见下面的@kgrittn评论


10
即使进行了澄清,从技术上讲也是错误的,并且可能会烧伤某人。例如,如果您认为x <> NULL解析为FALSE,则希望NOT (x <> NULL)评估为TRUE,但不会。 两者都评估为UNKNOWN。诀窍是只有在WHERE子句(如果存在)求和时才选择行TRUE-如果子句求值为FALSE或,则省略行UNKNOWN。这种行为(通常,NOT IN尤其是谓词)是SQL标准规定的。
kgrittn

同时NULL NOT IN (some_subquery)不应该返回外排除如果some_subquery不返回任何行。这就是为什么当两列都为Null时执行计划会变得更加昂贵的原因。SQL Server示例
Martin Smith
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.