Stell dir vor, jede Tabelle in deiner Datenbank ist ein Teil eines großen Puzzles. Die Tabelle students weiß, wer studiert, die Tabelle courses — was unterrichtet wird, und die Tabelle enrollments — wer worauf eingeschrieben ist. Aber einzeln sagen dir diese Teile nicht viel. Willst du das ganze Bild sehen? Dann musst du sie verbinden – und hier kommt der mehrfache JOIN ins Spiel.
Im echten Leben sind Daten oft in verbundene Tabellen organisiert, damit alles schön strukturiert bleibt und keine unnötigen Wiederholungen entstehen. Zum Beispiel gibt es in unserer Uni-Datenbank folgende Tabellen:
students— Infos über die Studierenden.enrollments— Infos darüber, auf welche Kurse die Studierenden eingeschrieben sind.courses— Infos über die Kurse.
Wenn wir eine komplette Liste der Studierenden, ihrer Kurse und Lehrenden haben wollen, müssen wir drei Tabellen mit JOIN zusammenbringen.
Reihenfolge der JOIN-Ausführung
Wenn du mehrere JOINs benutzt, arbeitet PostgreSQL sie von links nach rechts ab. Das heißt, zuerst werden die ersten beiden Tabellen verbunden, dann wird das Ergebnis mit der dritten Tabelle verbunden, und so weiter.
Beispiel:
SELECT *
FROM students
INNER JOIN enrollments ON students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id;
- Zuerst werden die Tabellen
studentsundenrollmentsüber die Spaltestudents.id = enrollments.student_idverbunden. - Das Ergebnis der ersten Verbindung wird dann mit der Tabelle
coursesüber die Spalteenrollments.course_id = courses.idverbunden.
Die Reihenfolge ist besonders wichtig, wenn große Tabellen im Spiel sind. Eine schlechte JOIN-Struktur kann die Performance echt runterziehen.
Beispiel: Liste der Studierenden, ihrer Kurse und Lehrenden
Nehmen wir an, wir haben folgende Tabellen mit Daten:
Tabelle students:
| id | name |
|---|---|
| 1 | Otto Song |
| 2 | Maria Chi |
| 3 | Alex Lin |
Tabelle courses:
| id | name | teacher |
|---|---|---|
| 101 | Mathematics | Ellen Moore |
| 102 | Physics | James Okoro |
| 103 | Computer Science | Nina Delgado |
Tabelle enrollments:
| student_id | course_id |
|---|---|
| 1 | 101 |
| 1 | 103 |
| 2 | 102 |
| 3 | 101 |
Abfrage:
SELECT
students.name AS student_name,
courses.name AS course_name,
courses.teacher AS teacher_name
FROM students
INNER JOIN enrollments ON students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id;
Ergebnis:
| student_name | course_name | teacher_name |
|---|---|---|
| Otto Song | Mathematics | Ellen Moore |
| Otto Song | Computer Science | Nina Delgado |
| Maria Chi | Physics | James Okoro |
| Alex Lin | Mathematics | Ellen Moore |
Filtern in Abfragen mit mehreren JOINs
Du kannst Filterbedingungen in Abfragen mit JOIN nutzen, um die Menge der zurückgegebenen Daten zu begrenzen und die Abfrage schneller zu machen. Zum Beispiel, wenn du nur die Studierenden sehen willst, die im Kurs "Mathematics" sind:
SELECT
students.name AS student_name,
courses.name AS course_name
FROM students
INNER JOIN enrollments ON students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id
WHERE courses.name = 'Mathematics';
Ergebnis:
| student_name | course_name |
|---|---|
| Otto Song | Mathematics |
| Alex Lin | Mathematics |
Abfrage-Optimierung mit mehreren JOINs
Wenn du mit großen Tabellen arbeitest, ist Abfrage-Optimierung super wichtig. Hier ein paar Tipps:
- Benutze Indizes
Indizes machen PostgreSQL schneller, besonders wenn du über Schlüsselspalten verbindest. Check, ob auf den Spalten student_id und course_id in der Tabelle enrollments Indizes liegen.
Beispiel für das Anlegen eines Index:
CREATE INDEX idx_enrollments_student_id ON enrollments(student_id);
CREATE INDEX idx_enrollments_course_id ON enrollments(course_id);
Mehr zu Indizes gibt’s in den nächsten Levels, aber ich wollte sie hier schon mal erwähnen. Sie hängen oft mit JOIN zusammen.
- Filtere Daten so früh wie möglich
Nutze WHERE-Bedingungen, um die Anzahl der Zeilen vor dem JOIN zu reduzieren. Zum Beispiel:
SELECT
students.name AS student_name,
courses.name AS course_name
FROM students
INNER JOIN enrollments ON students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id
WHERE
courses.teacher = 'Ivan Petrov';
- Minimiere die Anzahl der zu verbindenden Zeilen
Statt alle Einträge aus zwei Tabellen zu verbinden, filtere sie lieber vorher mit Subqueries:
SELECT
students.name AS student_name,
courses.name AS course_name
FROM
(SELECT * FROM students WHERE id IN (1, 2)) sub_students
INNER JOIN enrollments ON sub_students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id;
Mehr zu verschachtelten SELECTs gibt’s schon im nächsten Level :P
Beispiel für ein komplexes JOIN: Studierende, Kurse und Fakultäten
Nehmen wir an, es kommt noch eine Tabelle faculties dazu:
Tabelle faculties:
| id | name |
|---|---|
| 10 | Engineering |
| 20 | Natural Sciences |
Tabelle courses wird erweitert:
| id | name | teacher | faculty_id |
|---|---|---|---|
| 101 | Mathematics | Ellen Moore | 10 |
| 102 | Physics | James Okoro | 20 |
| 103 | Computer Science | Nina Delgado | 10 |
Um eine Liste der Studierenden, Kurse und Fakultäten zu bekommen, fügen wir noch einen JOIN hinzu:
SELECT
students.name AS student_name,
courses.name AS course_name,
faculties.name AS faculty_name
FROM students
INNER JOIN enrollments ON students.id = enrollments.student_id
INNER JOIN courses ON enrollments.course_id = courses.id
INNER JOIN faculties ON courses.faculty_id = faculties.id;
Ergebnis:
| student_name | course_name | faculty_name |
|---|---|---|
| Otto Song | Mathematics | Engineering |
| Otto Song | Computer Science | Engineering |
| Maria Chi | Physics | Natural Sciences |
| Alex Lin | Mathematics | Engineering |
SQL-Abfragen mit mehreren JOINs können ganz schön komplex werden, aber sie ermöglichen dir richtig mächtige Reports und wertvolle Insights. Wenn du sie richtig optimierst und strukturierst, werden sie zu deinem Tool für große Datenbanken.
GO TO FULL VERSION