CodeGym /Kurse /SQL SELF /Zusätzliche Bedingungen bei JOIN: ON...

Zusätzliche Bedingungen bei JOIN: ON ... AND ...

SQL SELF
Level 12 , Lektion 2
Verfügbar

Zusätzliche Bedingungen bei JOIN: ON ... AND ...

Du weißt schon, wie man Tabellen mit JOIN verbindet. Aber im echten Leben reicht einfaches Matchen nach Keys oft nicht aus. Oft brauchst du: Daten verbinden nur wenn sie noch einem weiteren Kriterium entsprechen – zum Beispiel nur aktive Einträge, nur Daten aus dem aktuellen Jahr oder nur abgeschlossene Bestellungen.

Und genau hier kommt die Erweiterung von ON mit AND ins Spiel.

Zusätzliche Bedingungen im JOIN ... ON erlauben dir ganz genau zu steuern, welche Zeilen beim Joinen dabei sind, noch bevor SQL das Ergebnis baut. Das macht die Abfrage:

  • Schneller (weniger Zeilen gehen durch den JOIN),
  • Genauer (gefiltert wird schon beim Joinen),
  • Vorhersehbarer bei LEFT JOIN (anders als beim Filtern im WHERE).

Beispiel: Nur aktive Kursanmeldungen

Nehmen wir an, die Tabelle enrollments enthält den Status der Teilnahme eines Studenten: active, dropped, pending.

Tabelle students:

id name
1 Otto Song
2 Maria Chi
3 Alex Lin

Aktualisierte Tabelle enrollments:

student_id course_id status
1 101 active
1 103 active
2 102 dropped
3 101 active

Tabelle courses:

id name
101 Mathematics
102 Physics
103 Computer Science

Jetzt wollen wir nur die Studenten mit aktiven Kursen bekommen:

SELECT 
    students.name AS student_name,
    courses.name AS course_name
FROM students 
INNER JOIN enrollments 
    ON students.id = enrollments.student_id
    AND enrollments.status = 'active'
INNER JOIN courses 
    ON enrollments.course_id = courses.id;

Ergebnis:

student_name course_name
Otto Song Mathematics
Otto Song Computer Science
Alex Lin Mathematics

Hier haben wir AND enrollments.status = 'active' in das ON gepackt, damit das Joinen nur für aktive Einträge passiert und nicht erst nach dem Join gefiltert wird.

Warum nicht WHERE?

Man könnte auch so schreiben:

...
WHERE enrollments.status = 'active'

Aber das verhält sich anders bei LEFT JOIN. Das Filtern im WHERE schmeißt Zeilen ohne Match (NULL) raus und macht so aus dem LEFT JOIN quasi einen INNER JOIN.

Das AND enrollments.status = 'active' im ON limitiert direkt die Zeilen, die gejoint werden – du steuerst, was überhaupt ins Join kommt, nicht nur das Endergebnis.

Das ist besonders wichtig, wenn du Zeilen aus einer Tabelle behalten willst, auch wenn es in der anderen keinen passenden Wert gibt (passiert oft bei Reports und Analytics).

Noch mehr Beispiele für ON ... AND ...

Tabelle students:

id name
1 Otto Song
2 Maria Chi
3 Alex Lin

Tabelle enrollments:

student_id course_id status enrolled_at
1 101 active 2025-02-01
1 103 active 2025-03-05
2 102 dropped 2024-05-15
3 101 active 2025-03-12

Tabelle courses:

id name
101 Math
102 Physics
103 CS

Beispiel: nur Kurse aus dem aktuellen Jahr

SELECT
    students.name,
    courses.name,
    enrollments.enrolled_at
FROM students
JOIN enrollments
    ON students.id = enrollments.student_id
    AND EXTRACT(YEAR FROM enrollments.enrolled_at) = EXTRACT(YEAR FROM CURRENT_DATE)
JOIN courses
    ON enrollments.course_id = courses.id;

Hier joinen wir nur die Einträge, die zum aktuellen Jahr gehören.

name name enrolled_at
Otto Song Math 2025-02-01
Otto Song CS 2025-03-05
Alex Lin Math 2025-03-12

Beispiel: Ausschluss nach Wert

JOIN enrollments
    ON students.id = enrollments.student_id
    AND enrollments.status != 'dropped'

Wir schließen Studenten, die rausgeflogen sind, schon beim Joinen aus, nicht erst danach.

name name
Otto Song Math
Otto Song CS
Alex Lin Math

Wenn die Bedingung im ON steht, kann PostgreSQL den Join-Plan optimieren und weniger Zeilen verarbeiten. Das ist bei großen Datenmengen besonders wichtig. Internes Filtern ist effizienter als "Aussieben" nach dem JOIN.

JOIN ON — das sind nicht nur Keys

Viele denken, ON ist einfach nur id = id. Aber du kannst da auch reinschreiben:

  • Logische Operatoren: AND, OR, NOT
  • Vergleiche: >, <, <>, BETWEEN, IN
  • Ausdrücke: EXTRACT, DATE_TRUNC, COALESCE, NULLIF

Alles kombinieren

Tabelle students:

id name
1 Otto Song
2 Maria Chi
3 Alex Lin

Tabelle faculties:

id name
10 Engineering
20 Natural Sciences
30 ← ohne Name (NULL)

Tabelle courses:

id name teacher faculty_id
101 Math Liam Park 10
102 Physics Chloe Zhang 20
103 CS Noah Kim 10
104 PE Ava Chen 30

Tabelle enrollments:

student_id course_id status
1 101 active
1 103 active
2 102 dropped
3 101 active
3 104 active
SELECT
    s.name AS student_name,
    c.name AS course_name,
    f.name AS faculty_name
FROM students s
JOIN enrollments e
    ON s.id = e.student_id
    AND e.status = 'active'
JOIN courses c
    ON e.course_id = c.id
    AND c.name != 'PE'
JOIN faculties f
    ON c.faculty_id = f.id
    AND f.name IS NOT NULL;

Hier filtern wir gleichzeitig nach:

  • Aktiven Einträgen,
  • Kursen außer "PE",
  • Fakultäten, die einen Namen haben.

Ergebnis der Abfrage:

student_name course_name faculty_name
Otto Song Math Engineering
Otto Song CS Engineering
Alex Lin Math Engineering

Ich hoffe, dir hat diese Vorlesung gefallen. Du wirst in deinen Abfragen sehr oft mehrere JOINs mit Filtern benutzen. Fast immer :)

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION