Premium

Äußerer Join: OUTER JOIN

Es gibt drei Arten des äußeren Joins: links (LEFT), rechts (RIGHT) und vollständig (FULL). Standardmäßig ist er vollständig.

Der Hauptunterschied zum inneren Join: Der äußere Join liefert immer alle Zeilen einer (LEFT, RIGHT) oder beider Tabellen (FULL).

Linker äußerer Join (LEFT OUTER JOIN)

Ein Join, der alle Werte aus der linken Tabelle liefert, kombiniert mit den passenden Werten aus der rechten Tabelle, sofern sie die Join-Bedingung erfüllen, oder andernfalls mit NULL aufgefüllt.

Als Beispiel holen wir aus der Datenbank den Klingelplan, verknüpft mit den passenden Einträgen aus dem Stundenplan.

Daten in der Tabelle Timepair (Klingelplan):

idstart_pairend_pair
108:30:0009:15:00
209:20:0010:05:00
310:15:0011:00:00
411:05:0011:50:00
512:50:0013:35:00
613:40:0014:25:00
714:35:0015:20:00
815:25:0016:10:00

Daten in der Tabelle Schedule (Stundenplan):

iddateclassnumber_pairteachersubjectclassroom
12019-09-01T00:00:00.000Z9111147
22019-09-01T00:00:00.000Z928213
32019-09-01T00:00:00.000Z934313
42019-09-02T00:00:00.000Z914313
52019-09-02T00:00:00.000Z922434
62019-09-02T00:00:00.000Z936535
72019-09-03T00:00:00.000Z915636
82019-09-03T00:00:00.000Z9213737
92019-09-03T00:00:00.000Z936838
102019-09-04T00:00:00.000Z919939
112019-09-04T00:00:00.000Z92101040
122019-09-04T00:00:00.000Z9331141
132019-09-05T00:00:00.000Z9131343
142019-09-05T00:00:00.000Z9211147
152019-09-05T00:00:00.000Z935636
162019-08-30T00:00:00.000Z912434
172019-08-30T00:00:00.000Z928213
182019-08-30T00:00:00.000Z936535
192019-08-30T00:00:00.000Z9410147
202019-09-03T00:00:00.000Z94101040
212019-08-30T00:00:00.000Z817953
222019-08-30T00:00:00.000Z827953
232019-08-30T00:00:00.000Z838238
242019-08-30T00:00:00.000Z8411143
252019-08-30T00:00:00.000Z858339
262019-09-01T00:00:00.000Z822434
272019-09-01T00:00:00.000Z836535
282019-09-01T00:00:00.000Z8412636
292019-09-01T00:00:00.000Z8513737
302019-09-02T00:00:00.000Z836838
312019-09-02T00:00:00.000Z847953
322019-09-03T00:00:00.000Z81101040
332019-09-03T00:00:00.000Z827953
342019-09-03T00:00:00.000Z837953
352019-09-04T00:00:00.000Z811114
362019-09-04T00:00:00.000Z8211242
372019-09-04T00:00:00.000Z8331343
382019-09-04T00:00:00.000Z848242
392019-09-04T00:00:00.000Z8511143
402019-09-05T00:00:00.000Z8211143
MySQL 8.1
SELECT Timepair.id "timepair.id", start_pair, end_pair,
    Schedule.id "schedule.id", date, class, number_pair, teacher, subject, classroom
FROM Timepair
    LEFT JOIN Schedule ON Schedule.number_pair = Timepair.id;
timepair.idstart_pairend_pairschedule.iddateclassnumber_pairteachersubjectclassroom
108:30:0009:15:00352019-09-04T00:00:00.000Z811114
108:30:0009:15:00322019-09-03T00:00:00.000Z81101040
108:30:0009:15:00212019-08-30T00:00:00.000Z817953
108:30:0009:15:00162019-08-30T00:00:00.000Z912434
108:30:0009:15:00132019-09-05T00:00:00.000Z9131343
108:30:0009:15:00102019-09-04T00:00:00.000Z919939
108:30:0009:15:0072019-09-03T00:00:00.000Z915636
108:30:0009:15:0042019-09-02T00:00:00.000Z914313
108:30:0009:15:0012019-09-01T00:00:00.000Z9111147
209:20:0010:05:00402019-09-05T00:00:00.000Z8211143
209:20:0010:05:00362019-09-04T00:00:00.000Z8211242
209:20:0010:05:00332019-09-03T00:00:00.000Z827953
209:20:0010:05:00262019-09-01T00:00:00.000Z822434
209:20:0010:05:00222019-08-30T00:00:00.000Z827953
209:20:0010:05:00172019-08-30T00:00:00.000Z928213
209:20:0010:05:00142019-09-05T00:00:00.000Z9211147
209:20:0010:05:00112019-09-04T00:00:00.000Z92101040
209:20:0010:05:0082019-09-03T00:00:00.000Z9213737
209:20:0010:05:0052019-09-02T00:00:00.000Z922434
209:20:0010:05:0022019-09-01T00:00:00.000Z928213
310:15:0011:00:00372019-09-04T00:00:00.000Z8331343
310:15:0011:00:00342019-09-03T00:00:00.000Z837953
310:15:0011:00:00302019-09-02T00:00:00.000Z836838
310:15:0011:00:00272019-09-01T00:00:00.000Z836535
310:15:0011:00:00232019-08-30T00:00:00.000Z838238
310:15:0011:00:00182019-08-30T00:00:00.000Z936535
310:15:0011:00:00152019-09-05T00:00:00.000Z935636
310:15:0011:00:00122019-09-04T00:00:00.000Z9331141
310:15:0011:00:0092019-09-03T00:00:00.000Z936838
310:15:0011:00:0062019-09-02T00:00:00.000Z936535
310:15:0011:00:0032019-09-01T00:00:00.000Z934313
411:05:0011:50:00382019-09-04T00:00:00.000Z848242
411:05:0011:50:00312019-09-02T00:00:00.000Z847953
411:05:0011:50:00282019-09-01T00:00:00.000Z8412636
411:05:0011:50:00242019-08-30T00:00:00.000Z8411143
411:05:0011:50:00202019-09-03T00:00:00.000Z94101040
411:05:0011:50:00192019-08-30T00:00:00.000Z9410147
512:50:0013:35:00392019-09-04T00:00:00.000Z8511143
512:50:0013:35:00292019-09-01T00:00:00.000Z8513737
512:50:0013:35:00252019-08-30T00:00:00.000Z858339
613:40:0014:25:00<NULL><NULL><NULL><NULL><NULL><NULL><NULL>
714:35:0015:20:00<NULL><NULL><NULL><NULL><NULL><NULL><NULL>
815:25:0016:10:00<NULL><NULL><NULL><NULL><NULL><NULL><NULL>

In die Ergebnismenge gelangen alle Zeilen der linken Tabelle, ergänzt um die Daten der Stundenplan-Einträge. Auffällig ist, dass am Ende der Tabelle Zeilen stehen, deren Felder mit NULL gefüllt sind. Das sind die Zeilen, für die keine passenden Stundenplaneinträge gefunden wurden — da sie aber in der linken Tabelle stehen, werden sie trotzdem ausgegeben.

Rechter äußerer Join (RIGHT OUTER JOIN)

Ein Join, der alle Werte aus der rechten Tabelle liefert, kombiniert mit den passenden Werten aus der linken Tabelle, sofern sie die Join-Bedingung erfüllen, oder andernfalls mit NULL aufgefüllt.

Vollständiger äußerer Join (FULL OUTER JOIN)

Ein Join, der einen inneren Join zwischen den Datensätzen ausführt und das Ergebnis um einen linken und einen rechten äußeren Join ergänzt.

So läuft der vollständige Join intern ab:

  • Es wird eine Tabelle auf Basis des inneren Joins (INNER JOIN) gebildet.
  • Es werden die Zeilen der linken Tabelle ergänzt, die im Ergebnis fehlen (LEFT OUTER JOIN).
  • Es werden die Zeilen der rechten Tabelle ergänzt, die im Ergebnis fehlen (RIGHT OUTER JOIN).

Vollständigen Join in MySQL emulieren

Da MySQL FULL OUTER JOIN nicht unterstützt, kannst du ihn mit UNION ALL nachbauen:

MySQL 8.1
SELECT *
FROM linke_tabelle
LEFT JOIN rechte_tabelle
   ON rechte_tabelle.key = linke_tabelle.key

UNION ALL

SELECT *
FROM linke_tabelle
RIGHT JOIN rechte_tabelle
ON rechte_tabelle.key = linke_tabelle.key
 WHERE linke_tabelle.key IS NULL

Grundlegende Queries für verschiedene Join-Varianten

SchemaQuery mit JOIN

Alle Daten der linken Tabelle, kombiniert mit den passenden Daten der rechten Tabelle:

MySQL 8.1
SELECT tabellen_felder 
FROM linke_tabelle LEFT JOIN rechte_tabelle 
    ON rechte_tabelle.key = linke_tabelle.key 

Alle Daten der rechten Tabelle, kombiniert mit den passenden Daten der linken Tabelle:

MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle RIGHT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key

Nur die Daten, die ausschließlich zur linken Tabelle gehören:

MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle LEFT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
WHERE rechte_tabelle.key IS NULL

Nur die Daten, die ausschließlich zur rechten Tabelle gehören:

MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle RIGHT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
WHERE linke_tabelle.key IS NULL

Daten, die sowohl zur linken als auch zur rechten Tabelle gehören:

MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle INNER JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key

Alle Daten, die zur linken und rechten Tabelle gehören, sowie ihr inneres Join-Ergebnis:

MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle
    FULL OUTER JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle
LEFT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key

UNION ALL

SELECT tabellen_felder
FROM linke_tabelle
RIGHT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
WHERE linke_tabelle.key IS NULL

Daten, die nicht gleichzeitig zur linken und rechten Tabelle gehören (das Gegenteil von INNER JOIN):

MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle
    FULL OUTER JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
WHERE linke_tabelle.key IS NULL
    OR rechte_tabelle.key IS NULL
MySQL 8.1
SELECT tabellen_felder
FROM linke_tabelle
LEFT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
WHERE rechte_tabelle.key IS NULL

UNION ALL

SELECT tabellen_felder
FROM linke_tabelle
RIGHT JOIN rechte_tabelle
    ON rechte_tabelle.key = linke_tabelle.key
WHERE linke_tabelle.key IS NULL