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.

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.

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 ...; 

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.

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.

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.

* 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