Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Daten abfragen und ändern » Abfrageergebnisse zusammenfassen, gruppieren und sortieren » Mengenoperationen auf Abfrageergebnissen mit UNION, INTERSECT und EXCEPT ausführen

 

Mengenoperatoren und NULL

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-2 immer 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;
col1 col2
2 b
4 (NULL)