SQL ist bereits angewandte Mengenlehre, wenn Sie so wollen. Dennoch bietet SQL die typischen aus der Mengenlehre bekannten Mengen-Operationen Vereinigung, Schnitt und Differenz, explizit an, um verschiedene Ergebnismengen damit zu verknüpfen.
Vereinigungsmenge UNION
Der UNION
-Operator ermöglicht es Ihnen, mehrere SELECT
-Statements zu einer Ergebnismenge zusammenzufassen, zu vereinigen. Dabei kennt er zwi Spielarten, ohne und mit dem Zusatz ALL
.
1 2 3 4 5 6 7 |
SELECT select_list FROM A UNION [ALL] SELECT select_list FROM B; |
Die Teilabfragen dürfen nicht beliebig sein. Sie müssen folgenden Kriterien gerecht werden:
- Die Anzahl der Spalten in der Ausgabeliste beider Abfragen muss gleich sein.
- Die Datentypen der abgefragten Spalten müssen zueinander kompatibel sein.
Der UNION
-Operator entfernt alle doppelten Zeilen aus den kombinierten Datensätzen. Das entspricht der klassischen Mengenlehre. Danach kommt jedes Element nur einmalig in einer Menge vor. Um eventuell doppelte Elemente, Zeilen, dennoch zu behalten, verwenden Sie UNION
mit dem Zusatz ALL
.
Das folgende Venn-Diagramm visualisiert die Wirkung von UNION
.

Ich habe in die Beispieldatenbank zwei Tabellen aufgenommen, top_rated_film
und most_popular_film
, anhand deren wir uns die Spielarten von UNION
sehr leicht verdeutlichen können.
UNION
code>ALL
Wir wollen uns die beliebtesten Filme anzeigen lassen. „Beliebt“ meint hierbei Filme, die entweder besonders gut bewertet wurden und/oder schlichtweg populär sind, weil häufig von den Kunden nachgefragt. – Nicht sehr praxisnah, sind die entsprechenden Filme in zwei Tabellen nachgehalten. In der Praxis würde man echte Bewertungen bzw. registrierte Nachfragen verwenden.
1 2 3 4 5 6 7 8 9 10 11 |
SELECT title FROM top_rated_film trf JOIN film f1 ON f1.film_id = trf.film_id UNION ALL SELECT title FROM most_popular_film mpf JOIN film f2 ON mpf.film_id = f2.film_id ORDER BY title; |
Beachten Sie, eine Sortierung erst am Ende vornehmen zu können. Es ist nicht möglich die Teilabfragen separat zu sortieren.
Wenn Sie sich die Tabellen vorher bereits angesehen haben, entspricht das Resultat der Abfrage vielleicht Ihren Erwartungen, alle Datensätze aus den Teilabfragen zusammengefasst angezeigt zu bekommen.
+-------------------+ |title | +-------------------+ |Badman Dawn | |Beach Heartbreakers| |Beach Heartbreakers| |Blade Polish | |Blade Polish | |Campus Remember | |Chainsaw Uptown | |Chainsaw Uptown | |Champion Flatliners| |Champion Flatliners| |Psycho Shrunk | |Psycho Shrunk | |Pure Runner | |Pure Runner | |Rocketeer Mother | |Spirit Flintstones | |Spirit Flintstones | |Storm Happiness | |Sugar Wonka | |Tarzan Videotape | +-------------------+
Doch sind wir ehrlich: Eigentlich wollen wir Dubletten nicht sehen.
UNION
UNION
verfügt sozusagen über ein implizites DISTINCT
. Das ist sogar die Voreinstellung, wenn Sie so wollen. Dann werden Dubletten in der Ausgabe automatisch entfernt. Tatsächlich ist das freilich ein wenig mehr Aufwand für den Server, in der Regel aber das (nicht immer), was wir wollen.
1 2 3 4 5 6 7 8 9 10 11 |
SELECT title FROM top_rated_film trf JOIN film f1 ON f1.film_id = trf.film_id UNION ALL SELECT title FROM most_popular_film mpf JOIN film f2 ON mpf.film_id = f2.film_id ORDER BY title; |
+-------------------+ |title | +-------------------+ |Badman Dawn | |Beach Heartbreakers| |Blade Polish | |Campus Remember | |Chainsaw Uptown | |Champion Flatliners| |Psycho Shrunk | |Pure Runner | |Rocketeer Mother | |Spirit Flintstones | |Storm Happiness | |Sugar Wonka | |Tarzan Videotape | +-------------------+
Schnittmenge INTERSECT
Wir können uns auch Fragen, welche Filme besonders gut bewertet und gleichzeitig populär sind. Die Antwort auf diese Frage entspricht der Schnittmenge der beiden Teilabfragen, die Sie bereits kennen.

1 2 3 4 5 6 7 8 9 10 11 |
SELECT title FROM top_rated_film trf JOIN film f1 ON f1.film_id = trf.film_id INTERSECT SELECT title FROM most_popular_film mpf JOIN film f2 ON mpf.film_id = f2.film_id ORDER BY title; |
+-------------------+ |title | +-------------------+ |Beach Heartbreakers| |Blade Polish | |Chainsaw Uptown | |Champion Flatliners| |Psycho Shrunk | |Pure Runner | |Spirit Flintstones | +-------------------+
Differenzmenge EXCEPT
Schließlich können wir auch Fragen, welche Filme zwar Top-Bewertungen haben, aber dennoch nicht zu den gefragtesten Filmen gehören. Umgekehrt können wir das auch Fragen, was ein anderes Resultat liefert. Während es bei Vereinigung und Schnitt egal ist, in welcher Reihenfolge wir die jeweilige Operation ausführen, ist die Reihenfolge bei der Differenzbildung signifikant.
1 2 3 4 5 6 7 8 9 10 11 |
SELECT -- Top-Filme title FROM top_rated_film trf JOIN film f1 ON f1.film_id = trf.film_id EXCEPT SELECT -- ohne beliebteste Filme title FROM most_popular_film mpf JOIN film f2 ON mpf.film_id = f2.film_id ORDER BY title; |
+----------------+ |title | +----------------+ |Badman Dawn | |Campus Remember | |Rocketeer Mother| +----------------+
1 2 3 4 5 6 7 8 9 10 11 |
SELECT -- beliebteste Filme title FROM most_popular_film mpf JOIN film f2 ON mpf.film_id = f2.film_id EXCEPT SELECT -- ohne Top-Filme title FROM top_rated_film trf JOIN film f1 ON f1.film_id = trf.film_id ORDER BY title; |
+----------------+ |title | +----------------+ |Storm Happiness | |Sugar Wonka | |Tarzan Videotape| +----------------+
Anmerkung: INTERSECT
, UNION
und EXCEPT
können in einer Abfrage gemeinsam verwendet werden. Dabei ist die Priorität der Operatoren zu beachten. Die höchste Priorität hat INTERSECT
, dann kommt UNION
und am Ende EXCEPT
.