JOINs

Geschätzte Lektüre: 10 Minuten 119 Ansichten

Ein JOIN kombiniert Zeilen aus zwei oder mehr Tabellen basierend auf einer verwandten Spalte zwischen ihnen. Die Syntax folgt diesem Muster:

SELECT spalten
FROM tabelle1
JOIN-TYP tabelle2 ON tabelle1.schluessel = tabelle2.schluessel;

Wir unterscheiden verschiedene JOIN-Typen. Die wichtigsten werden wir nun im Detail betrachten.


INNER JOIN – Die Schnittmenge

Der INNER JOIN ist der am häufigsten verwendete JOIN-Typ. Er gibt nur diejenigen Zeilen zurück, für die in beiden Tabellen ein übereinstimmender Wert in der JOIN-Bedingung existiert. Zeilen ohne Entsprechung in der anderen Tabelle werden nicht im Ergebnis angezeigt.

Beispiel 1: Bestellungen mit Kundennamen

Wir möchten eine Liste aller Bestellungen sehen, ergänzt um den Namen des jeweiligen Kunden.

SELECT 
    b.id AS bestellungsnummer,
    k.vorname,
    k.nachname,
    b.bestelldatum,
    b.status
FROM bestellungen b
INNER JOIN kunden k ON b.kunden_id = k.id;

Ergebnis: Jede Bestellung erscheint, und wir sehen die zugehörigen Kundendaten. Bestellungen ohne Kunden (was durch den Fremdschlüssel sowieso verhindert wird) oder Kunden ohne Bestellungen erscheinen nicht.

Beispiel 2: Bestellpositionen mit Produktnamen

Wir möchten detailliert sehen, welche Produkte in welchen Bestellungen enthalten sind.

SELECT 
    bp.bestellung_id,
    p.name AS produktname,
    bp.menge,
    bp.einzelpreis,
    (bp.menge * bp.einzelpreis) AS positionswert
FROM bestellpositionen bp
INNER JOIN produkte p ON bp.produkt_id = p.id;

Beispiel 3: Mehrere JOINs kombinieren

Wir möchten eine vollständige Bestellübersicht mit Kundennamen, Produktnamen und Mengen.

SELECT 
    k.nachname,
    k.vorname,
    b.id AS bestellung_id,
    b.bestelldatum,
    p.name AS produkt,
    bp.menge,
    bp.einzelpreis
FROM bestellungen b
INNER JOIN kunden k ON b.kunden_id = k.id
INNER JOIN bestellpositionen bp ON b.id = bp.bestellung_id
INNER JOIN produkte p ON bp.produkt_id = p.id
ORDER BY b.id, p.name;

Dies ist eine typische Abfrage in einem Bestellsystem. Wir sehen, wie alle vier Tabellen über ihre Schlüsselbeziehungen miteinander verknüpft werden.


LEFT JOIN und RIGHT JOIN – Inklusive Ergebnismengen

Während INNER JOIN nur Übereinstimmungen zeigt, geben LEFT JOIN und RIGHT JOIN auch Zeilen aus der einen Tabelle zurück, für die keine Entsprechung in der anderen Tabelle existiert.

LEFT JOIN

Ein LEFT JOIN gibt alle Zeilen aus der linken Tabelle (der Tabelle vor dem LEFT JOIN) zurück, unabhängig davon, ob es eine Übereinstimmung in der rechten Tabelle gibt. Für Zeilen ohne Übereinstimmung werden die Spalten der rechten Tabelle mit NULL gefüllt.

Beispiel: Alle Kunden, auch solche ohne Bestellungen

SELECT 
    k.id,
    k.vorname,
    k.nachname,
    COUNT(b.id) AS anzahl_bestellungen
FROM kunden k
LEFT JOIN bestellungen b ON k.id = b.kunden_id
GROUP BY k.id, k.vorname, k.nachname;

Ergebnis: Alle fünf Kunden erscheinen. Kunden ohne Bestellungen (in unserem Beispiel ist das Kunde 5, Elena Fischer) erhalten den Wert 0 für anzahl_bestellungen. Mit einem INNER JOIN wäre dieser Kunde komplett ausgeblieben.

Beispiel: Bestellungen ohne Positionen (Fehlersuche)
Angenommen, wir möchten prüfen, ob es Bestellungen gibt, die keine Positionen enthalten.

SELECT 
    b.id AS bestellung_id,
    b.bestelldatum
FROM bestellungen b
LEFT JOIN bestellpositionen bp ON b.id = bp.bestellung_id
WHERE bp.id IS NULL;

Diese Abfrage findet Bestellungen, für die keine verknüpfte Zeile in bestellpositionen existiert. In unserem Beispieldatenbestand sollte dies kein Ergebnis liefern.


RIGHT JOIN

RIGHT JOIN funktioniert spiegelbildlich zum LEFT JOIN: Es gibt alle Zeilen aus der rechten Tabelle zurück. RIGHT JOIN lässt sich in der Praxis häufig durch einen LEFT JOIN ersetzen, indem man die Tabellenreihenfolge vertauscht. Wir konzentrieren uns daher primär auf LEFT JOIN, der in der Praxis gebräuchlicher ist.

-- Äquivalente Abfragen
SELECT * FROM kunden LEFT JOIN bestellungen ON kunden.id = bestellungen.kunden_id;
SELECT * FROM bestellungen RIGHT JOIN kunden ON bestellungen.kunden_id = kunden.id;

Vollständige Praxisanalyse mit allen JOIN-Typen

Zum Abschluss dieser Lektion führen wir eine umfassende Analyse unseres Bestellsystems durch, die verschiedene JOIN-Typen und Aggregationen kombiniert.

Aufgabe 1: Umsatz pro Kunde
Wir berechnen, welcher Kunde welchen Gesamtumsatz generiert hat. Dabei sollen alle Kunden aufgelistet werden – auch solche ohne Bestellungen.

SELECT 
    k.id,
    k.nachname,
    k.vorname,
    COALESCE(SUM(bp.menge * bp.einzelpreis), 0) AS gesamtumsatz
FROM kunden k
LEFT JOIN bestellungen b ON k.id = b.kunden_id
LEFT JOIN bestellpositionen bp ON b.id = bp.bestellung_id
GROUP BY k.id, k.nachname, k.vorname
ORDER BY gesamtumsatz DESC;

Die Funktion COALESCE wandelt NULL-Werte (bei Kunden ohne Bestellungen) in 0 um.

Aufgabe 2: Produkte, die noch nie bestellt wurden
Wir möchten Produkte identifizieren, die sich noch nie in einer Bestellung befanden. Dies ist eine typische LEFT JOIN-Abfrage mit NULL-Filter.

SELECT 
    p.id,
    p.name,
    p.preis
FROM produkte p
LEFT JOIN bestellpositionen bp ON p.id = bp.produkt_id
WHERE bp.produkt_id IS NULL;

Aufgabe 3: Detaillierte Bestellübersicht mit Status
Für jede Bestellung zeigen wir den Kunden, die Anzahl der enthaltenen Produkte und den Gesamtwert an.

SELECT 
    b.id AS bestellnummer,
    CONCAT(k.vorname, ' ', k.nachname) AS kunde,
    b.bestelldatum,
    b.status,
    COUNT(bp.id) AS anzahl_positionen,
    SUM(bp.menge * bp.einzelpreis) AS gesamtwert
FROM bestellungen b
INNER JOIN kunden k ON b.kunden_id = k.id
LEFT JOIN bestellpositionen bp ON b.id = bp.bestellung_id
GROUP BY b.id, k.vorname, k.nachname, b.bestelldatum, b.status
ORDER BY b.bestelldatum DESC;

Führen Sie diese Abfragen in Ihrer phpMyAdmin-Umgebung aus. Beobachten Sie, wie die unterschiedlichen JOIN-Typen das Ergebnis beeinflussen. Mit INNER JOIN würden Bestellungen ohne Positionen (in unseren Daten nicht vorhanden) oder Kunden ohne Bestellungen komplett wegfallen. Der LEFT JOIN in der Verknüpfung zu bestellpositionen stellt sicher, dass auch Bestellungen ohne Positionen (wenn es sie gäbe) mit einem Gesamtwert von NULL erscheinen würden.


Wichtige Hinweise zur JOIN-Praxis

Bei der Arbeit mit JOINs in Ihrer Entwicklungsumgebung sollten wir folgende Punkte beachten:

Aliase (AS) verwenden: Wenn wir mehrere Tabellen verknüpfen, werden die Spaltennamen oft mehrdeutig. Verwenden wir Tabellen-Aliase, wie wir es mit b, k, bp, p getan haben. Das macht die Abfrage kürzer und lesbarer.

Fremdschlüssel-Constraints: Die FOREIGN KEY-Definitionen, die wir beim Erstellen der Tabellen mitgegeben haben, stellen die referenzielle Integrität sicher. ON DELETE RESTRICT verhindert, dass ein Kunde gelöscht wird, wenn noch Bestellungen existieren. ON DELETE CASCADE bei bestellpositionen sorgt dafür, dass beim Löschen einer Bestellung automatisch auch alle zugehörigen Positionen gelöscht werden. Diese Constraints sind nicht zwingend für JOINs erforderlich, aber sie sind essenziell für die Datenkonsistenz in einer professionellen Datenbank.

Performance: JOINs über große Tabellen können rechenintensiv sein. Daher stellen wir i.d.R. sicher, dass die Spalten, die wir für JOIN-Bedingungen verwenden (in der Regel Primär- und Fremdschlüssel), indiziert sind. In MySQL sind Primärschlüssel automatisch indiziert, Fremdschlüssel sollten wir bei großen Datenmengen ebenfalls indizieren. Für unsere Lernumgebung ist dies nicht erforderlich.

Dieses Dokument teilen

JOINs

Oder Link kopieren

INHALT

Abonnieren

×
Cancel