Dies ist eine alte Version des Dokuments!
LU09a: SELECT über mehrere Tabellen (INNER JOIN & WHERE)
Ziel: Sie können Daten aus mehreren Tabellen abfragen – mit INNER JOIN … ON (empfohlen) und der älteren WHERE-Variante. Sie verstehen, welche Tabelle in FROM steht, welche in JOIN folgt, und ob die Reihenfolge bei mehr als zwei Tabellen eine Rolle spielt.
Voraussetzung: DB aus LU08c (users, posts, categories, post_category) ist erstellt und mit Beispieldaten gefüllt.
1) Warum JOINs? Kurze Einordnung
In relationalen DBs verteilen wir Daten auf mehrere Tabellen (z. B. Autor:innen → users, Beiträge → posts). Abfragen über mehrere Tabellen verbinden wir mit JOINs – verknüpft werden Primärschlüssel (PK) und Fremdschlüssel (FK).
Ohne Beziehung können wir Tabellen nur einzeln ansehen:
SELECT * FROM users; SELECT * FROM posts; SELECT * FROM categories; SELECT * FROM post_category;
Sinnvoll wird es erst, wenn wir diese Infos in einer Ergebnisliste zusammenführen – dafür brauchen wir JOINs.
2) Allgemeine Syntax (zuerst die Theorie)
Empfohlen (modern & klar): INNER JOIN … ON
SELECT t1.spalten, t2.spalten FROM t1 INNER JOIN t2 ON t1.fk = t2.pk -- optional weitere Verknüpfungen: INNER JOIN t3 ON t2.fk = t3.pk WHERE ... -- filtern ORDER BY ...; -- sortieren
Ältere Schreibweise (funktional gleichwertig): FROM + WHERE
SELECT t1.spalten, t2.spalten FROM t1, t2, t3 WHERE t1.fk = t2.pk AND t2.fk = t3.pk AND ... -- weitere Filter ORDER BY ...;
3) Welche Tabelle in FROM – und welche in JOIN? Spielt die Reihenfolge eine Rolle?
Grundregel (für INNER JOIN):
* In FROM steht die „führende“ Tabelle – jene, deren Zeilen Sie primär listen möchten (z. B. posts, wenn Sie Posts auflisten). * Alles, was Sie zusätzlich brauchen, kommt in JOIN (z. B. users für den Autorname, categories via post_category).
Reihenfolge bei mehreren INNER JOINs:
* Bei INNER JOIN ändert die Reihenfolge das Ergebnis nicht, solange alle Join-Bedingungen korrekt sind. * Didaktisch & lesbar: vom Bedarf her denken (z. B. *Posts anzeigen*), entlang der Schlüsselbeziehungen „weiterjoinen“:
- 1:n: `posts → users`
- n:m (via Junction): `posts → post_category → categories`
Sonderfall Junction-Table (N:M):
* Starten Sie mit der Tabelle, die Sie auflisten wollen (FROM posts). * Dann JOIN auf die Junction (post_category) und weiter auf die Zieltabelle (categories). * So bleibt der Join-Pfad klar, die Abfrage lesbar.
4) Warm-up: Posts mit Autor:in (2 Tabellen)
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 – WHERE-Schreibweise:
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;
Mögliches Resultat:
| 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 |
Aliase (p, u) verkürzen Schreibarbeit und erhöhen Lesbarkeit.
5) Drei Tabellen: Posts mit Kategorien (N:M via Junction)
Schritt-für-Schritt mit INNER JOIN (empfohlen):
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;
Dasselbe als WHERE-Variante:
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 |
Merke (N:M): Pro Kategorie entsteht eine Ergebniszeile. Ein Post mit 3 Kategorien erscheint dreimal – das ist korrekt.
6) Filtern & Sortieren – wo kommt die WHERE-Klausel hin?
* JOIN-Bedingungen gehören bei der JOIN-Schreibweise in ON. * Inhaltliche Filter (z. B. nur bestimmte Autor:innen/Kategorien) kommen in WHERE. * ORDER BY bestimmt die Ausgabe-Reihenfolge.
Beispiele:
* Alle Posts in der Kategorie „staedtereise“:
<WRAP center box 80% round><code sql> 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; </code></WRAP>
* Alle Posts von Caro Steig, mit Kategorien:
<WRAP center box 80% round><code sql> 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; </code></WRAP>
- modul/m290_guko/learningunits/lu09/theorie/a_select_multiple_tables.1761509884.txt.gz
- Zuletzt geändert: 2025/10/26 21:18
- von gkoch