Warum gibt NOT IN mit einer Menge, die NULL enthält, immer FALSE / NULL zurück?

21

Ich hatte eine Abfrage (für Postgres und Informix) mit einer NOT INKlausel, die eine Unterabfrage enthielt, die in einigen Fällen NULLWerte zurückgab , was dazu führte, dass diese Klausel (und die gesamte Abfrage) nichts zurückgab .

Wie kann man das am besten verstehen? Ich dachte an NULLetwas ohne Wert und erwartete daher nicht, dass die Abfrage fehlschlägt, aber offensichtlich ist dies nicht die richtige Art zu denken NULL.

Newenglander
quelle

Antworten:

29

Boolesche Logik - oder Dreiwertige Logik

  • IN ist eine Abkürzung für eine Reihe von OR-Bedingungen
  • x NOT IN (1, 2, NULL) ist das gleiche wie NOT (x = 1 OR x = 2 OR x = NULL)
  • ... ist das gleiche wie x <> 1 AND x <> 2 AND x <> NULL
  • ... ist dasselbe wie true AND true AND unknown**
  • ... = unknown**
  • ... das ist fast das gleiche wie falsein diesem Fall, da es die WHEREBedingung nicht erfüllt **

Dies ist der Grund, warum die Leute EXISTS+ NOT EXISTSanstatt IN+ verwenden NOT IN. Siehe auch die Verwendung von NOT - Logik in Bezug auf Indizes für mehr

** Hinweis: unknownist die gleiche wie falseam Ende eines Ausdrucks in einem WHEREZustand.
Während der Auswertung des Ausdrucks ist nicht bekannt,
warum

gbn
quelle
10
Selbst mit der Klärung ist es technisch falsch und auf eine Weise, die jemanden verbrennen könnte. Wenn Sie x <> NULLbeispielsweise eine Auflösung für anzeigen FALSE, erwarten Sie, dass NOT (x <> NULL)die Auswertung für erfolgt TRUE, und dies ist nicht der Fall. Beide werten zu aus UNKNOWN. Der Trick besteht darin, dass eine Zeile nur dann ausgewählt wird, wenn die WHEREKlausel (falls vorhanden) als - ausgewertet wird. TRUEEine Zeile wird weggelassen, wenn die Klausel entweder als FALSEoder ausgewertet wird UNKNOWN. Dieses Verhalten (im Allgemeinen und für das NOT INPrädikat im Besonderen) wird vom SQL-Standard vorgeschrieben.
kgrittn
Außerdem NULL NOT IN (some_subquery)sollte die äußere Zeile some_subquerynicht zurückgegeben werden, es sei denn, es werden keine Zeilen zurückgegeben. Aus diesem Grund kann der Ausführungsplan, wenn beide Spalten nullfähig sind, erheblich teurer sein. SQL Server-Beispiel
Martin Smith