Zählen mit LEFT JOIN
Mit LEFT JOIN kannst du sogar Dinge zählen, die gar kein Gegenstück haben. Wie viele Bestellungen hat jeder Kunde aufgegeben, auch die Kunden, die keine aufgegeben haben?
SELECT k.name, COUNT(*) AS anzahl_zeilen, COUNT(b.id) AS anzahl_bestellungen
FROM kunden AS k
LEFT JOIN bestellungen AS b ON b.kunde_id = k.id
GROUP BY k.id, k.name
ORDER BY anzahl_bestellungen, k.name;| name | anzahl_zeilen | anzahl_bestellungen |
|---|---|---|
| Hannes Schulz | 1 | 0 |
| Max Krause | 1 | 0 |
| Ida Zimmermann | 1 | 1 |
| Anna Fischer | 2 | 2 |
| … | … | … |
Sieh dir Hannes Schulz an: COUNT(*) sagt 1, COUNT(b.id) sagt 0. Warum? COUNT(*) zählt Zeilen, und das LEFT JOIN hat Hannes eine Zeile gegeben, die mit NULL in den Spalten von bestellungen. COUNT(b.id) zählt nur die Werte, die nicht NULL sind (das kennst du aus der Lektion über das Gruppieren), und in Hannes' einziger Zeile ist b.id NULL. Es sagt also 0, und das ist die richtige Antwort. Ida Zimmermann hat eine echte Bestellung und in beiden Spalten eine 1.
Wenn du also nach einem LEFT JOIN die Gegenstücke zählst, benutze nicht COUNT(*). Zähle eine Spalte der rechten Tabelle, die in einem echten Gegenstück nie NULL ist, dieselbe, die du mit IS NULL prüfen würdest: ihren Primärschlüssel oder eine Spalte mit NOT NULL.
SUM, AVG, MIN und MAX überspringen NULL ebenfalls, und für eine Gruppe, die nur aus NULL besteht, geben sie NULL zurück, nicht 0. Das Geld, das ein Kunde ohne Bestellungen ausgegeben hat, käme als NULL heraus. Wenn du eine 0 willst, benutze COALESCE aus der Lektion über Funktionen: COALESCE(SUM(p.menge * p.preis), 0).
Typischer Fehler: Zählen mit einem einfachen JOIN. Die Kunden ohne Bestellungen sind weg, bevor GROUP BY läuft, das Ergebnis hat also gar keine Nullen, und nichts verrät dir, dass jemand fehlt.
So schreibst du es:
Anweisungen
- 1
Zeige für jedes Spiel, wie viele Bewertungen es hat: den
titelund die Zahl alsanzahl_bewertungen. Die Spiele ohne Bewertung müssen mit 0 dabei sein. Sortiere die Zeilen nachanzahl_bewertungen, dann nachtitel:titel anzahl_bewertungen Castle Siege 0 Lost Temple 0 Mystery Manor 0 Robot Rebellion 0 Bakery Story 1 … … - 2
Zeige darunter, wie viele Exemplare jedes Spiels die Kunden bestellt haben, erstattete Bestellungen eingeschlossen: den
titelund die Summe der Mengen alsexemplare. Für die Spiele, die niemand bestellt hat, mussexemplare0 sein, nicht NULL. Sortiere die Zeilen nachexemplare, dann nachtitel:titel exemplare Lost Temple 0 Mystery Manor 0 Robot Rebellion 0 Castle Siege 1 Goal Rush 2 Ice Hockey Pro 2 Ocean Deep 2 Star Pilots 2 … …