NULLを含むセットでNOT INが常にFALSE / NULLを返すのはなぜですか?


21

NOT IN場合によってはNULL値を返すサブクエリを含む句を含むクエリ(PostgresおよびInformix)があり、その句(およびクエリ全体)が何も返さないことがありました。

これを理解する最良の方法は何ですか?私NULLは値のないものと考えていたため、クエリが失敗することを期待していませんでしたが、明らかにそれは正しい考え方ではありませんNULL

回答:


29

ブール論理-または3値論理

  • 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と同じです。 式が評価されている間は不明 です。理由については、以下の@kgrittnのコメントを参照してください。falseWHERE


10
明確にしたとしても、それは技術的に間違っており、誰かを燃やす可能性があります。たとえば、にx <> NULL解決すると見なす場合FALSENOT (x <> NULL)に評価することが期待されますがTRUE、そうではありません。 両方とも評価されUNKNOWNます。トリックは、WHERE句(存在する場合)が評価される場合にのみ行が選択TRUEされることです。句がFALSEまたはに評価される場合、行は省略されますUNKNOWN。この動作(一般的にNOT INは、特に述語の場合)は、SQL標準で義務付けられています。
kgrittn

またNULL NOT IN (some_subquery)、行をsome_subquery返さない場合を除き、外側の行を返さないでください。これが、両方の列がNull可能の場合の実行計画がかなり高価になる理由です。SQL Serverの例
マーティンスミス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.