Mittwoch, 9. Januar 2008

EXISTS vs. IN

Ich hatte hier eine Abfrage in einer gespeicherten Prozedur nach dem Schema

INSERT INTO Tabelle1
SELECT DISTINCT Spalte1, Spalte2, Spalte3
FROM Tabelle 2
WHERE Spalte3 NOT IN
(SELECT Spalte3b FROM Tabelle1);

Also nimm alle Datensätze aus Tabelle2, deren Spalte3 keine Entsprechung in Spalte3b der Tabelle1 hat und füge diese in die Tabelle 1 ein. Also um sicher zu stellen, dass jeder Datensatz nur ein mal in Tabelle 1 eingefügt wird. Hat bisher prima funktioniert. Nur heute war das einzufügende Resultset leer, obwohl nachweislich Daten da waren, die das Kriterium erfüllten.

Rätsel, Rätsel, Recherchier, Recherchier und siehe da: Die gute alte NULL war mal wieder schuld an allem. Ist in dem Resultset der Unterabfrage (SELECT Spalte3b FROM Tabelle2) eine NULL enthalten, so führt das zum "dritten" Booleanwert unknown, weshalb die gesamte Bedingung falsch wird.
Besser man nutzt EXISTS, was die NULL-Werte ignoriert:


INSERT INTO Tabelle1
SELECT DISTINCT Spalte1, Spalte2, Spalte3
FROM Tabelle2
WHERE NOT EXISTS
(SELECT * FROM Tabelle1 WHERE Tabelle1.Spalte3b = Tabelle2.Spalte3);

et voila!

entsprechender Thread bei theScripts