LEFT JOIN: auch Zeilen ohne Partner
Kurz gesagt: LEFT JOIN behält jede Zeile der linken Tabelle, auch die ohne Partner in der rechten Tabelle, und füllt die fehlenden Spalten mit NULL.
Problem
Wer hat noch nicht bestellt?
Das Marketing will den Kunden schreiben, die sich angemeldet, aber noch nichts bestellt haben. In der letzten Lektion lieferte JOIN 60 Zeilen, und Teodora und Yavor waren nicht darunter.
JOIN behält nur die Paare. Eine Zeile ohne Partner verschwindet ohne Warnung. Hier sind das genau die Zeilen, die wir brauchen.
Die Idee
LEFT JOIN
Vergleiche die beiden Abfragen. Die erste benutzt JOIN:
Die zweite benutzt LEFT JOIN:
62 Zeilen statt 60. LEFT JOIN behält jede Zeile der linken Tabelle (der in FROM), auch wenn es in der rechten keinen Partner gibt. Wo es keinen Partner gibt, sind die Spalten der rechten Tabelle NULL. Scrolle ans Ende: Teodora und Yavor sind da, mit NULL für Nummer und Datum.
Von hier sind die Kunden ohne Bestellungen nur einen Schritt entfernt:
WHERE o.id IS NULL behält nur die Zeilen, in denen keine Bestellung gefunden wurde. Wir prüfen o.id, weil der Primärschlüssel einer gefundenen Bestellung nie leer ist.
Sieh es dir an
Auch eine leere Antwort ist eine Antwort
Gibt es Produkte, die noch nie jemand bestellt hat? Dasselbe Vorgehen, mit order_items:
Keine einzige Zeile. Jedes der 25 Produkte wurde mindestens einmal bestellt. Eine Tabelle ohne Zeilen ist kein Fehler: Die Abfrage hat geantwortet „es gibt keine“.
Probier es aus
Die leeren Kategorien
Welche Kategorien haben kein Produkt direkt in sich? Zeige den Namen der Kategorie.
Lösung
SELECT cat.name
FROM categories cat
LEFT JOIN products p ON p.category_id = cat.id
WHERE p.id IS NULL;FROM categories cat LEFT JOIN products p ON p.category_id = cat.id WHERE p.id IS NULL. „Lebensmittel“ und „Haushalt“. Das sind die obersten Kategorien: Die Produkte liegen in ihren Unterkategorien. Mit einem einfachen JOIN kommen sie gar nicht heraus.
Sieh es dir an
Zählen mit den Nullen
Wie viele Bestellungen hat jeder Kunde, auch die ohne? Ein erster Versuch mit COUNT(*):
Teodora und Yavor haben je 1 Bestellung? Nein. COUNT(*) zählt Zeilen, und LEFT JOIN hat jedem von ihnen eine Zeile voller NULL gegeben. Zähle, was einen Wert hat, COUNT(o.id):
COUNT(Spalte) überspringt die NULL, also kommen sie mit 0 heraus. Zähle bei LEFT JOIN eine Spalte der rechten Tabelle, am besten ihren Primärschlüssel.
Probier es aus
Bewertungen pro Produkt
Zeige jedes Produkt und wie viele Bewertungen es hat, auch die Produkte ohne Bewertung (mit 0).
Lösung
SELECT p.name, COUNT(r.id) AS reviews
FROM products p
LEFT JOIN reviews r ON r.product_id = p.id
GROUP BY p.id, p.name;FROM products p LEFT JOIN reviews r ON r.product_id = p.id GROUP BY p.id, p.name mit COUNT(r.id). 25 Zeilen. Mit COUNT(*) würden die Produkte ohne Bewertung 1 zeigen, und mit JOIN würden sie fehlen.
Sieh es dir an
Die WHERE-Falle
Ein Bericht für den Oktober: alle Kunden und wie viele Bestellungen sie seit dem 1. Oktober 2026 aufgegeben haben. Die Datumsbedingung kommt in WHERE:
Fünf Zeilen, aber es gibt 20 Kunden. Eine Bedingung auf die rechte Tabelle in WHERE macht aus einem LEFT JOIN einen einfachen JOIN. Ihr Platz ist in ON: Dort sagt sie, welche Bestellungen verbunden werden, und alle Kunden bleiben.
20 Kunden, die meisten mit 0. Die Regel: Bei LEFT JOIN kommt eine Bedingung auf die rechte Tabelle in ON. Die Ausnahme ist IS NULL, wenn du die Fehlenden suchst.
Übung
Zwei Aufgaben
1. Der Shop will die Kunden, die noch keine Bewertung geschrieben haben, einladen, eine zu schreiben. Wer sind sie? Zeige den Namen.
Die Kunden ohne eine einzige Bewertung:
Lösung
SELECT c.name
FROM customers c
LEFT JOIN reviews r ON r.customer_id = c.id
WHERE r.id IS NULL;FROM customers c LEFT JOIN reviews r ON r.customer_id = c.id WHERE r.id IS NULL. Sechs: Petya, Martin, Simona, Hristo, Teodora und Yavor.
2. Die Kampagne „Wir vermissen dich“ gilt den Kunden, die seit dem 1. Juli 2026 keine Bestellung aufgegeben haben (auch denen, die nie bestellt haben). Zeige Name und E-Mail.
Die Kunden ohne Bestellung seit dem 2026-07-01:
Lösung
SELECT c.name, c.email
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id AND o.ordered_at >= '2026-07-01'
WHERE o.id IS NULL;Das Datum gehört in ON, und IS NULL in WHERE: LEFT JOIN orders o ON o.customer_id = c.id AND o.ordered_at >= '2026-07-01' WHERE o.id IS NULL. 10 Kunden. Steht das Datum in WHERE, kommt niemand heraus: Die Zeilen mit NULL fallen wegen des Datums weg, und die Zeilen mit einem Datum fallen wegen IS NULL weg.
Genauer, für Neugierige
Es gibt auch RIGHT JOIN (behält die Zeilen der rechten Tabelle) und FULL JOIN (behält beide Seiten). SQLite versteht sie seit Version 3.39. RIGHT JOIN schreibt man selten: Es ist dasselbe wie LEFT JOIN mit vertauschten Tabellen. MySQL hat kein FULL JOIN.
Hier kommen nur die Kunden ohne Bestellungen heraus, denn jede Bestellung hat einen Kunden.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Aggregatfunktionen: COUNT, SUM, AVG · GROUP BY: ein Bericht nach Gruppen · Primärschlüssel und Fremdschlüssel · JOIN: zwei Tabellen in einer Abfrage
- Geht weiter in: Viele Tabellen und eine Tabelle mit sich selbst verbunden · UNION, INTERSECT, EXCEPT und CROSS JOIN · Eine Auswertung in Schritten: WITH · Bäume und Folgen: WITH RECURSIVE
- Aufgaben zum Thema: Tabellen verbinden