TL;DR
- UNION stapelt Zeilen aus mehreren Abfragen untereinander. Es fügt keine Spalten hinzu, das macht ein JOIN.
- Alle Teilabfragen brauchen dieselbe Spaltenanzahl, dieselbe Spaltenreihenfolge und kompatible Datentypen.
- UNION entfernt doppelte Zeilen, UNION ALL behält jede Zeile und ist meist schneller.
- Spaltennamen kommen aus der ersten Abfrage, ORDER BY steht einmal ganz am Ende.
- Für Berichte ist UNION ALL mit einer Spalte für die Herkunft oft die sicherere Wahl.
Inhaltsverzeichnis
Was UNION in SQL macht
Stellen Sie sich zwei Excel-Listen mit identischem Aufbau vor: Kunden aus Deutschland in der einen, Kunden aus Österreich in der anderen. Sie wollen eine Gesamtliste, also kopieren Sie die zweite Liste unter die erste. Genau das erledigt UNION in SQL, nur direkt in der Datenbank und ohne Kopieren.
Microsoft beschreibt UNION in der SQL-Server-Dokumentation als Verkettung der Ergebnisse zweier Abfragen zu einem einzigen Ergebnis, das alle Zeilen aller beteiligten Abfragen enthält. Es ist ein sogenannter Mengenoperator: Er arbeitet nicht mit einzelnen Werten, sondern mit ganzen Ergebnismengen.
Wichtig für das Verständnis: Die Teilabfragen müssen nicht aus derselben Tabelle stammen und die Tabellen müssen auch nicht gleich gebaut sein. Entscheidend ist nur, dass die Ergebnisse zueinander passen. Die PostgreSQL-Dokumentation spricht deshalb von „union compatible“ Abfragen: gleiche Spaltenanzahl, passende Datentypen. Sie können also Daten aus völlig unterschiedlichen Tabellen zusammenführen, solange Sie die Spalten vorher passend auswählen und umbenennen.
Die Syntax und ihre drei Regeln
Die Grundform ist in allen gängigen Datenbanken gleich:
SELECT spalte1, spalte2 FROM tabelle_a
UNION [ALL]
SELECT spalte1, spalte2 FROM tabelle_b;
Sie können beliebig viele Abfragen aneinanderreihen, indem Sie weitere UNION-Blöcke anhängen. Drei Regeln gelten dabei immer:
- Gleiche Spaltenanzahl. Liefert die erste Abfrage drei Spalten, müssen alle anderen ebenfalls drei liefern. Sonst bricht die Datenbank mit einer Fehlermeldung ab.
- Gleiche Reihenfolge. SQL ordnet die Spalten nach ihrer Position zu, nicht nach ihrem Namen. Steht in der ersten Abfrage vorname, nachname und in der zweiten nachname, vorname, landen die Nachnamen in der Vornamen-Spalte, ohne Fehlermeldung.
- Kompatible Datentypen. Eine Textspalte und eine Datumsspalte an derselben Position passen in der Regel nicht zusammen. Notfalls wandeln Sie mit CAST um.
Die zweite Regel ist die tückischste, weil die Abfrage technisch funktioniert und trotzdem falsche Daten liefert. Laut
MySQL-Referenzhandbuch sollen die zusammengehörigen Ausdrücke deshalb sauber nach Position ausgerichtet werden.
Ein Beispiel Schritt für Schritt
Angenommen, Sie haben zwei Tabellen mit Kunden:
kunden_de
| kunden_id | name | stadt |
| 1 | Anna Berger | Hamburg |
| 2 | Jonas Weber | Köln |
| 3 | Lea Schmitt | Leipzig |
kunden_at
| kunden_id | name | stadt |
| 3 | Lea Schmitt | Leipzig |
| 7 | Max Huber | Graz |
Lea Schmitt steht in beiden Tabellen, weil sie in beiden Shops bestellt hat. Die Abfrage:
SELECT name, stadt FROM kunden_de
UNION
SELECT name, stadt FROM kunden_at;
liefert vier Zeilen: Anna Berger, Jonas Weber, Lea Schmitt und Max Huber. Die doppelte Zeile ist verschwunden. Mit UNION ALL statt UNION erhalten Sie fünf Zeilen, Lea Schmitt taucht dann zweimal auf.
Welche Variante richtig ist, hängt von der Frage ab. Wollen Sie wissen, wer überhaupt Kunde ist, passt UNION. Wollen Sie wissen, wie viele Kundenkonten es gibt, brauchen Sie UNION ALL.
UNION vs. UNION ALL: der Unterschied
Das ist die häufigste Frage zum Thema, und die Antwort ist kurz: UNION entfernt doppelte Ergebniszeilen, UNION ALL behält alle. So steht es sowohl bei PostgreSQL als auch bei Microsoft. MySQL nennt das Entfernen der Duplikate ausdrücklich das Standardverhalten und erlaubt zusätzlich das Schlüsselwort UNION DISTINCT, das dasselbe bewirkt wie ein einfaches UNION.
| Kriterium | UNION | UNION ALL |
| Doppelte Zeilen | werden entfernt | bleiben erhalten |
| Zeilenanzahl im Ergebnis | kleiner oder gleich der Summe | genau die Summe aller Teilabfragen |
| Zusätzlicher Rechenaufwand | ja, für die Duplikatprüfung | nein |
| Typischer Einsatz | eindeutige Listen (E-Mail-Verteiler, Stammdaten) | Transaktionen, Ereignisse, Zeitreihen |
| Risiko | gültige Wiederholungen gehen verloren | echte Duplikate bleiben drin |
Ein Duplikat ist die ganze Zeile
Viele Einsteiger erwarten, dass UNION doppelte Kunden-IDs entfernt. Tatsächlich vergleicht die Datenbank aber alle ausgewählten Spalten. Zwei Zeilen gelten nur dann als Duplikat, wenn jede Spalte übereinstimmt. Hat Lea Schmitt in der einen Tabelle die Stadt „Leipzig“ und in der anderen „Leipzig “ mit Leerzeichen am Ende, bleiben beide Zeilen stehen.
Daraus folgen zwei praktische Hinweise: Wählen Sie nur die Spalten aus, die Sie wirklich brauchen, denn jede zusätzliche Spalte macht Duplikate unwahrscheinlicher. Und wenn ein Schlüssel wie die Kunden-ID allein eindeutig sein muss, reicht UNION nicht. Dann brauchen Sie eine eigene Deduplizierung, etwa mit GROUP BY über die ID.
Performance: Warum UNION ALL meist schneller ist
Um Duplikate zu finden, muss die Datenbank das Gesamtergebnis vergleichen, in der Regel durch Sortieren oder Hashen. Das kostet bei großen Datenmengen spürbar Zeit. In der bekannten Diskussion auf Stack Overflow wird genau dieser Mehraufwand als Grund genannt, warum UNION ALL schneller läuft. UNION ALL hängt die Zeilen einfach an.
Unsere Faustregel: Nehmen Sie UNION ALL, wenn Duplikate echte Ereignisse sind oder durch den Aufbau der Daten gar nicht vorkommen können. Nehmen Sie UNION nur, wenn Sie bewusst doppelte Zeilen loswerden wollen. Prüfen Sie danach in beiden Fällen die Zeilenanzahl.
UNION vs. JOIN: Zeilen stapeln oder Spalten ergänzen
UNION und JOIN kombinieren beide Daten aus mehreren Quellen, aber in verschiedene Richtungen. Microsoft bringt es in der Transact-SQL-Referenz auf den Punkt: Ein UNION verkettet Ergebnismengen, ein JOIN vergleicht Spalten zweier Tabellen und bildet daraus Zeilen mit Spalten aus beiden Quellen.
| UNION | JOIN |
| Richtung | vertikal: mehr Zeilen | horizontal: mehr Spalten |
| Voraussetzung | gleiche Spaltenstruktur der Ergebnisse | eine gemeinsame Verknüpfung, z. B. eine ID |
| Excel-Vergleich | zweite Liste unter die erste kopieren | Werte per SVERWEIS oder XVERWEIS dazuholen |
| Beispiel | Umsätze 2025 und 2026 in einer Liste | Bestellungen mit Kundennamen anreichern |
Der typische Fehler: Jemand will zu jeder Bestellung den Kundennamen haben und greift zu
UNION. Das Ergebnis ist eine lange Liste, in der Bestellungen und Kunden untereinander stehen, statt nebeneinander. Die Abfrage läuft fehlerfrei, der Bericht ist trotzdem falsch. Fragen Sie sich deshalb vor jeder Abfrage: Brauche ich
mehr Zeilen derselben Art oder
mehr Informationen zu denselben Zeilen? Im ersten Fall UNION, im zweiten JOIN.
Sortieren, Spaltennamen, Datentypen: die häufigsten Fehler
ORDER BY gehört ans Ende
Ein ORDER BY in der Mitte einer UNION-Abfrage führt je nach Datenbank zu einem Fehler oder wird ignoriert. Setzen Sie es einmal hinter die letzte Teilabfrage, dann sortiert es das Gesamtergebnis:
SELECT name, stadt FROM kunden_de
UNION ALL
SELECT name, stadt FROM kunden_at
ORDER BY name;
Das MySQL-Handbuch empfiehlt dasselbe auch für LIMIT. Braucht eine einzelne Teilabfrage ein eigenes ORDER BY mit LIMIT, etwa „die fünf neuesten Bestellungen aus jedem Shop“, setzen Sie diese Teilabfrage in Klammern. Und verlassen Sie sich nie darauf, dass die Zeilen der ersten Abfrage zuerst erscheinen: Ohne abschließendes ORDER BY garantiert SQL keine Reihenfolge.
Spaltennamen kommen aus der ersten Abfrage
In PostgreSQL und MySQL bestimmt die erste Teilabfrage die Spaltennamen des Ergebnisses. Aliase in späteren Teilabfragen benennen nichts um. Vergeben Sie sprechende Namen deshalb immer in der ersten Abfrage, und beziehen Sie sich im ORDER BY auf diese Namen.
Fehlende Spalten auffüllen
Hat eine Quelle eine Spalte nicht, füllen Sie die Lücke mit einer Konstanten oder einem NULL. Damit der Datentyp stimmt, hilft eine Typumwandlung:
SELECT kunden_id, betrag FROM bestellungen
UNION ALL
SELECT kunden_id, CAST(NULL AS decimal(12,2)) AS betrag FROM newsletter_anmeldungen;
Die genaue Schreibweise für Datentypen unterscheidet sich zwischen den Systemen. Schlagen Sie im Zweifel in der Dokumentation Ihrer Datenbank nach.
Ein Praxis-Muster für Berichte
In der Praxis landen Daten oft auf mehrere Tabellen verteilt: ein Jahr pro Tabelle, ein Land pro Tabelle, ein System pro Tabelle. Für Analysten und alle, die ihre Berichte selbst bauen, hat sich dieses Muster bewährt:
SELECT kunden_id, betrag, '2025' AS quelle FROM umsatz_2025
UNION ALL
SELECT kunden_id, betrag, '2026' FROM umsatz_2026;
Das leistet die Abfrage:
- Einheitliches Schema: Beide Teilabfragen liefern dieselben Spalten in derselben Reihenfolge.
- Herkunft bleibt sichtbar: Die Spalte quelle zeigt bei jeder Zeile, woher sie stammt. So können Sie später nach Jahr filtern oder gruppieren.
- Keine stillen Verluste: UNION ALL behält jede Transaktion. Hat ein Kunde zweimal denselben Betrag bezahlt, bleiben beide Zahlungen erhalten. Mit UNION würde eine davon verschwinden, und Ihr Umsatz wäre zu niedrig.
Sie können das Ergebnis anschließend wie eine normale Tabelle weiterverarbeiten, etwa als Unterabfrage mit
GROUP BY quelle für eine Umsatzsumme pro Jahr. Ein kurzer Plausibilitätscheck gehört immer dazu: Die Zeilenanzahl des Ergebnisses muss bei
UNION ALL der Summe der Einzelabfragen entsprechen.
Die anderen Mengenoperatoren: INTERSECT, EXCEPT und MINUS
UNION hat Geschwister. Zusammen bilden sie die Mengenoperationen in SQL):
| Operator | Ergebnis | Hinweis |
| UNION | alle Zeilen beider Abfragen, ohne Duplikate | Standard in allen gängigen Systemen |
| UNION ALL | alle Zeilen beider Abfragen, mit Duplikaten | Standard in allen gängigen Systemen |
| INTERSECT | nur Zeilen, die in beiden Abfragen vorkommen | z. B. Kunden in beiden Shops |
| EXCEPT | Zeilen der ersten Abfrage, die in der zweiten fehlen | in PostgreSQL, SQL Server, MySQL, SQLite |
| MINUS | wie EXCEPT | Name in Oracle |
Oracle führt in seiner
Referenz zu den Mengenoperatoren UNION,
UNION ALL,
INTERSECT und
MINUS auf und gibt allen den gleichen Vorrang. MySQL dagegen dokumentiert
INTERSECT und
EXCEPT, kennt
MINUS als Operatornamen aber nicht. Auch
SQLite unterstützt UNION, UNION ALL, INTERSECT und EXCEPT.
Beachten Sie: EXCEPT und MINUS sind gerichtet. Vertauschen Sie die beiden Abfragen, ändert sich das Ergebnis. Und wer eine Abfrage zwischen Systemen kopiert, sollte vorher prüfen, welche Operatoren die Zieldatenbank kennt.
Unsere Sicht: UNION lernt man durch Tippen, nicht durch Lesen
Wir sehen bei LogicExcel jeden Tag, woran Lernende scheitern: nicht am Konzept, sondern an den Details. Die meisten verstehen nach zwei Minuten, dass UNION Zeilen stapelt. Trotzdem vertauschen sie beim ersten eigenen Versuch die Spaltenreihenfolge, setzen das ORDER BY in die Mitte oder verlieren mit UNION stillschweigend doppelte Transaktionen. Das sind genau die Fehler, die in einem echten Bericht teuer werden, weil keine Fehlermeldung warnt.
Deshalb setzen wir auf aktives Üben statt passiver Tutorials. Wer eine Abfrage selbst schreibt, sofort Feedback bekommt und die Erklärung zur eigenen Antwort liest, baut das Muskelgedächtnis auf, das beim Lesen fehlt. Das gilt für SQL genauso wie für Excel-Formeln: SVERWEIS, INDEX/VERGLEICH und ZÄHLENWENN sitzen erst dann, wenn man sie ein paar Dutzend Mal getippt hat.
Unser Rat an Berufseinsteiger, Quereinsteiger und Analysten: Lernen Sie UNION und JOIN als Paar. Wer beide sicher unterscheidet, versteht, wie Daten zusammengeführt werden, egal ob in einer Datenbank oder in einer Excel-Tabelle. Und gewöhnen Sie sich an, nach jeder Kombination die Zeilen zu zählen. Diese eine Gewohnheit verhindert mehr falsche Berichte als jede fortgeschrittene Technik.
> — Thomas Houza
Üben, bis es sitzt
Wenn Sie Datenabfragen und die Excel-Grundlagen dahinter festigen wollen: Auf LogicExcel lösen Sie 95 kostenlose Excel-Übungen direkt im Browser, ohne Anmeldung und ohne Installation. Neben Formeln, Funktionen, Pivot-Tabellen und Shortcuts gehören auch SQL-Befehle zum Übungsangebot, jeweils mit sofortigem Feedback und einer verständlichen Erklärung zu jeder Antwort. Wer strukturiert vorgehen möchte, findet in unseren Kursen von „Working With Sheets“ bis „Lookups and Logic“ einen klaren Lernpfad.
Häufige Fragen
Was ist der Unterschied zwischen UNION und UNION ALL?
UNION entfernt doppelte Ergebniszeilen,
UNION ALL behält alle Zeilen, auch Duplikate. Als Duplikat gilt nur eine Zeile, die in allen ausgewählten Spalten übereinstimmt.
UNION ALL ist in der Regel schneller, weil die Duplikatprüfung entfällt.
Müssen die Spaltennamen bei UNION gleich sein?
Nein. Entscheidend sind die Anzahl der Spalten, ihre Reihenfolge und kompatible Datentypen. Die Namen im Ergebnis stammen aus der ersten Abfrage, Aliase in späteren Teilabfragen werden ignoriert.
Kann ich mehr als zwei Abfragen mit UNION verbinden?
Ja, Sie können beliebig viele SELECT-Abfragen mit UNION oder UNION ALL aneinanderreihen. Achten Sie darauf, dass alle dieselbe Spaltenstruktur liefern. Ein ORDER BY steht nur einmal, nach der letzten Abfrage.
Wann nehme ich UNION und wann JOIN?
UNION nehmen Sie, wenn Sie gleichartige Zeilen aus mehreren Quellen untereinander zusammenführen wollen, etwa Umsätze aus zwei Jahren. JOIN nehmen Sie, wenn Sie zu bestehenden Zeilen weitere Spalten aus einer anderen Tabelle brauchen, etwa den Kundennamen zur Bestellung.
Warum fehlen nach meiner UNION-Abfrage Zeilen?
Meist hat UNION Zeilen entfernt, die in allen Spalten identisch waren, zum Beispiel zwei gleich hohe Zahlungen desselben Kunden. Ersetzen Sie UNION durch UNION ALL und vergleichen Sie die Zeilenanzahl mit der Summe der Einzelabfragen.
Quellen