Ich habe zwei Tabellen:Warum ruft IN nicht immer dieselben Ergebnisse wie MINUS in Oracle ab?
CREATE TABLE test1
(id int);
CREATE TABLE test2
(id int);
INSERT INTO test1
VALUES (1);
INSERT INTO test1
VALUES (2);
INSERT INTO test2
VALUES (1);
Dann möchte ich eine Liste aller IDs sehen, die in test1 sind und nicht in test2.
Es gibt mindestens drei Möglichkeiten, wie ich denken kann, dies zu tun:
OUTER JOIN:
SELECT a.id
FROM test1 a LEFT OUTER JOIN test2 b
ON a.id = b.id
WHERE b.id IS NULL;
MINUS:
SELECT id
FROM test1
MINUS
SELECT id
FROM test2;
NICHT IN:
So weit, so gut. Alle drei dieser Abfragen sollten mir die gleichen Ergebnisse geben: 1 Zeile mit dem Wert 2.
Wenn ich eine Null in Test2 einfügen, dann die OUTER JOIN und MINUS Abfragen weiterhin die gleichen Ergebnisse, aber die NOT IN bringt keine Zeilen zurück.
Das hat mich sehr verwirrt. Ich bemerkte dann, dass, wenn ich es zu
SELECT id
FROM test1
WHERE id NOT IN (
SELECT id
FROM test2
WHERE id IS NOT NULL
);
änderte, dass ich die Ergebnisse erhalte, die ich erwartete - eine Reihe wieder.
Warum tritt dies auf? Ich gehe davon aus, dass dies etwas fundamentales für SQL ist, aber ich weiß nicht, was es ist (und ich bin ziemlich sicher, dass in anderen Datenbanken, die ich bereits erwähnt habe, gleichwertige Ergebnisse erzielt haben - obwohl ich nicht Habe jetzt keinen SQL Server oder Postgres zum Testen, daher kann ich mich über ihr Verhalten ärgern.
(Ich nehme an, eine Antwort darauf lautet: "Mach dir keine Sorgen, und benutze NOT IN nicht"), aber das kann in Bezug auf die Lesbarkeit von Code teuer sein - manchmal ist das eleganter als alles mit Outer Joins oder Minus.
"etwas ziemlich fundamental zu SQL": Definitiv. 'NULL' macht dir in Vergleichen nie gut. 'NULL' ist weder gleich noch ungleich zu irgendetwas, nicht einmal sich selbst. – Thilo
null ist kein Wert, aber ein unbekannter –