NULL wird von den Mengenoperatoren UNION, EXCEPT und INTERSECT anders behandelt, als dies in Suchbedingungen der Fall ist.
Der Unterschied ist einer der Hauptgründe dafür, Mengenoperatoren zu verwenden.
Wenn Zeilen verglichen werden, behandeln Mengenoperatoren NULL gleichwertig. Wenn dagegen NULL mit NULL in einer Suchbedingung
verglichen wird, ist das Ergebnis unbekannt (nicht TRUE).
Eine Konsequenz dieses Unterschieds liegt darin, dass die Zeilenanzahl in der Ergebnismenge für query-1 EXCEPT ALL query-2immer die Differenz der Zeilenanzahl in den Ergebnismengen der einzelnen Abfragen ist.
Nehmen wir zum Beispiel zwei Tabellen T1 und T2, jeweils mit den folgenden Spalten:
col1 INT,
col2 CHAR(1)
Tabellen und Daten werden wie folgt eingerichtet:
CREATE TABLE T1 (col1 INT, col2 CHAR(1));
CREATE TABLE T2 (col1 INT, col2 CHAR(1));
INSERT INTO T1 (col1, col2) VALUES(1, 'a');
INSERT INTO T1 (col1, col2) VALUES(2, 'b');
INSERT INTO T1 (col1) VALUES(3);
INSERT INTO T1 (col1) VALUES(3);
INSERT INTO T1 (col1) VALUES(4);
INSERT INTO T1 (col1) VALUES(4);
INSERT INTO T2 (col1, col2) VALUES(1, 'a');
INSERT INTO T2 (col1, col2) VALUES(2, 'x');
INSERT INTO T2 (col1) VALUES(3);
Die Daten in den Tabellen sind Folgende:
Tabelle T1
col1
col2
1
a
2
b
3
(NULL)
3
(NULL)
4
(NULL)
4
(NULL)
Tabelle T2
col1
col2
1
a
2
x
3
(NULL)
Die folgende Abfrage sucht nach Zeilen in T1, die auch in T2 vorkommen:
SELECT T1.col1, T1.col2
FROM T1 JOIN T2
ON T1.col1 = T2.col1
AND T1.col2 = T2.col2;
T1.col1
T1.col2
1
a
Die Zeile ( 3, NULL ) kommt nicht in der Ergebnismenge vor, da der Vergleich zwischen NULL und NULL nicht TRUE ist. Wenn dagegen
das Problem mit dem INTERSECT-Operator behandelt wird, wird eine Zeile mit NULL einbezogen:
SELECT col1, col2
FROM T1
INTERSECT
SELECT col1, col2
FROM T2;
col1
col2
1
a
3
(NULL)
Die folgende Abfrage verwendet Suchbedingungen, um Zeilen aufzulisten, die in T1, aber nicht in T2 vorkommen:
SELECT col1, col2
FROM T1
WHERE col1 NOT IN (
SELECT col1
FROM T2
WHERE T1.col2 = T2.col2 )
OR col2 NOT IN (
SELECT col2
FROM T2
WHERE T1.col1 = T2.col1 );
col1
col2
2
b
3
(NULL)
4
(NULL)
3
(NULL)
4
(NULL)
Die NULL-enthaltenden Zeilen von T1 werden durch den Vergleich nicht ausgeschlossen. Wenn dagegen das Problem unter Verwendung
von EXCEPT ALL behandelt wird, werden NULL-enthaltende Zeilen ausgeschlossen, die in beiden Tabellen vorkommen. In diesem
Fall wird die Zeile (3, NULL) in T2 als gleichwertig mit der Zeile (3, NULL) in T1 identifiziert.
SELECT col1, col2
FROM T1
EXCEPT ALL
SELECT col1, col2
FROM T2;
col1
col2
2
b
3
(NULL)
4
(NULL)
4
(NULL)
Der EXCEPT-Operator ist sogar noch restriktiver. Er eliminiert beide Zeilen (3, NULL) von T1 und schließt eine der Zeilen
(4, NULL) als mehrfach vorhanden aus.
SELECT col1, col2
FROM T1
EXCEPT
SELECT col1, col2
FROM T2;