Dies ist eine alte Version des Dokuments!
LU09a: SELECT über mehrere Tabellen (INNER JOIN & WHERE)
Ziel: Sie können Daten aus mehreren Tabellen abfragen – einmal mit INNER JOIN … ON, einmal mit der älteren Schreibweise (mehrere Tabellen nach FROM, Verknüpfung in der WHERE-Klausel).
Voraussetzung: DB aus LU08c (users, posts, categories, post_category) ist erstellt und mit Beispieldaten gefüllt.
1) Warum JOINs? Kurzer Überblick
In unserem Reiseblog liegen Infos verteilt:
Autor:innen → users
Beiträge → posts (mit author_id)
Kategorien → categories
Zuordnung Post↔Kategorie → post_category
Um zum Beispiel Posttitel + Autorname zusammen zu sehen, müssen wir posts und users verbinden.
2) Zwei Schreibweisen – gleiche Bedeutung
Variante A – INNER JOIN … ON (empfohlen):
SELECT p.post_id, p.title, u.display_name AS author FROM posts AS p INNER JOIN users AS u ON p.author_id = u.user_id ORDER BY p.post_id;
Variante B – „alte“ Schreibweise mit WHERE:
SELECT p.post_id, p.title, u.display_name AS author FROM posts p, users u WHERE p.author_id = u.user_id ORDER BY p.post_id;
Beispielresultat:
| post_id | title | author |
|---|---|---|
| 1 | Hasselt – 10 Highlights | Martin Merten |
| 2 | Utrecht – 10 Sehenswürdigkeiten | Martin Merten |
| 3 | Lissabon – 8 Tipps zu den wichtigsten Sehenswürdigkeiten | Caro Steig |
| 4 | Maastricht an einem Tag | Caro Steig |
| 5 | Montenegro Roadtrip – 10 Highlights | Caro Steig |
| 6 | Oman – Top 22 Highlights | Caro Steig |
| 7 | Chicago in 3 Tagen – 17 Highlights | Martin Merten |
Merke: Beide Varianten liefern identische Resultate. Die JOIN-Schreibweise ist heute Standard, besser lesbar und reduziert Fehler (z. B. fehlende Join-Bedingungen).
3) Über drei Tabellen (Posts ↔ Kategorien)
Ein Post kann mehrere Kategorien haben (N:M). Die Verbindung läuft über post_category.
a) Alle Posts mit allen Kategorien (JOIN):
SELECT p.title, c.name AS category FROM posts p INNER JOIN post_category pc ON p.post_id = pc.post_id INNER JOIN categories c ON pc.category_id = c.category_id ORDER BY p.post_id, c.name;
b) Dasselbe mit WHERE-Schreibweise:
SELECT p.title, c.name AS category FROM posts p, post_category pc, categories c WHERE p.post_id = pc.post_id AND pc.category_id = c.category_id ORDER BY p.post_id, c.name;
Ausschnitt (mögliche Ausgabe):
| title | category |
|---|---|
| Hasselt – 10 Highlights | Belgien |
| Hasselt – 10 Highlights | Städtereise |
| Utrecht – 10 Sehenswürdigkeiten | Niederlande |
| Utrecht – 10 Sehenswürdigkeiten | Städtereise |
| Lissabon – 8 Tipps zu den wichtigsten Sehenswürdigkeiten | Portugal |
| Lissabon – 8 Tipps zu den wichtigsten Sehenswürdigkeiten | Städtereise |
Hinweis N:M: Pro Kategorie entsteht eine Zeile. Hat ein Post 3 Kategorien, erscheinen 3 Zeilen – das ist korrekt.
4) Filtern (WHERE) & Sortieren (ORDER BY)
Beispiele:
Alle Posts in der Kategorie „Städtereise“:
SELECT p.title FROM posts p INNER JOIN post_category pc ON p.post_id = pc.post_id INNER JOIN categories c ON pc.category_id = c.category_id WHERE c.slug = 'staedtereise' ORDER BY p.title;
Alle Posts von Caro Steig, mit ihren Kategorien:
SELECT p.title, c.name AS category FROM posts p INNER JOIN users u ON p.author_id = u.user_id INNER JOIN post_category pc ON p.post_id = pc.post_id INNER JOIN categories c ON pc.category_id = c.category_id WHERE u.display_name = 'Caro Steig' ORDER BY p.title, c.name;
5) Typische Fehler & schnelle Checks
Fehlende Join-Bedingung → Ergebnis explodiert (Kreuzprodukt). Prüfen: Hat jede Tabellenverbindung genau eine ON/WHERE-Bedingung?
Falscher Alias → „Unknown column“.
Prüfen: Stimmen Kurzbezeichnungen (p/u/pc/c) überall?
Doppelte Zeilen unerwartet → Oft N:M-Join.
Prüfen: Ist die Mehrfachzuordnung beabsichtigt? Sonst DISTINCT verwenden (bewusst!).
Lernziel-Check: Sie können INNER JOIN und die WHERE-Variante sicher anwenden und über 2–3 Tabellen abfragen.

