Jetzt bist du bereit für den nächsten Schritt – die Arbeit mit verschachtelten Abfragen in SQL. Heute schauen wir uns an, was das ist, wozu man sie braucht, welche Typen es gibt und warum sie im echten Leben praktisch sind.
Verschachtelte Abfragen (oder Subqueries) sind SQL-Abfragen, die innerhalb anderer SQL-Abfragen verwendet werden. So eine Art Matrjoschka oder Kohlkopf: Es gibt eine äußere Abfrage, und darin versteckt sich eine andere, kleinere Abfrage. Die Subquery wird zuerst ausgeführt und ihr Ergebnis wird von der äußeren Abfrage (manchmal auch "Hauptabfrage" genannt) verwendet.
Schauen wir uns das mal an einem Beispiel an:
Beispiel 1: Wie funktioniert das?
Wir haben eine Tabelle students mit folgenden Daten:
| id | name | alter | gruppe_id |
|---|---|---|---|
| 1 | Alisa | 20 | 1 |
| 2 | Bob | 22 | 2 |
| 3 | Klark | 21 | 1 |
| 4 | Dina | 23 | 3 |
| 5 | Emilia | 22 | 2 |
Und außerdem gibt es die Tabelle groups, in der die Namen der Gruppen gespeichert sind:
| id | bezeichnung |
|---|---|
| 1 | Mathematische Klasse |
| 2 | Physikalische Klasse |
| 3 | Literarische Klasse |
Wenn wir wissen wollen, wie die Gruppen heißen, in denen die Studenten lernen, können wir eine verschachtelte Abfrage benutzen:
SELECT bezeichnung
FROM groups
WHERE id IN (
SELECT gruppe_id
FROM students
WHERE alter > 21
);
Was passiert hier?
Die verschachtelte Abfrage:
SELECT gruppe_id
FROM students
WHERE alter > 21
Diese Abfrage wählt gruppe_id von allen Studenten, die älter als 21 sind. Ergebnis: eine Liste von Gruppen-IDs, zum Beispiel [2, 3].
Die Hauptabfrage:
SELECT bezeichnung
FROM groups
WHERE id IN ([Ergebnisse der Subquery])
Diese Abfrage nutzt die Ergebnisse der Subquery und gibt die Namen der Gruppen mit id 2 oder 3 zurück.
Ergebnis:
Physikalische Klasse
Literarische Klasse
Immer noch nichts verstanden? Verständlich. Aber keine Sorge, wir klären das gleich.
Fangen wir mit einer einfachen Idee an – das Ergebnis einer SELECT-Abfrage ist eine Art virtuelle Tabelle. Sie hat Spalten, sie hat Zeilen. Warum also keine Tabelle?
Und wenn das Ergebnis einer Abfrage eine Tabelle ist, kann man sie auch dort verwenden, wo man echte Tabellen benutzt: zum Beispiel im JOIN-Operator oder in komplexeren Konstruktionen.
Sie hat keinen Namen, und das ist ein Problem. Aber auch Spaltenausdrücke haben keinen Namen, und das lösen wir mit Aliases – also Spitznamen. Das kann man auch mit virtuellen Tabellen machen.
Mehr dazu in den nächsten Lektionen – wir wollen ja nicht spoilern :P
Warum verschachtelte Abfragen nützlich sind
Sie machen komplexe Aufgaben einfacher. Manchmal enthält eine Tabelle nicht alle Infos, die du brauchst. Subqueries erlauben es, die Abfrage in zwei Schritte zu teilen: Erst holst du ein Zwischenergebnis, dann nutzt du das für die endgültigen Daten.
Arbeiten mit Zwischenergebnissen. Verschachtelte Abfragen sind praktisch, wenn du vor der Verarbeitung noch Berechnungen machen musst. Zum Beispiel einen Minimalwert finden oder eine Summe berechnen.
Bessere Lesbarkeit vom Code. Subqueries machen den Code strukturierter, besonders wenn du mit großen Tabellen und komplexer Logik arbeitest.
Die wichtigsten Typen von verschachtelten Abfragen
Verschachtelte Abfragen kann man an verschiedenen Stellen im SQL-Statement verwenden. Je nachdem, wo du sie schreibst, gibt es verschiedene Typen.
- Subqueries im
SELECT. Die Subquery steht in der Spaltenliste und wird benutzt, um Werte zu berechnen. Das ist praktisch, um zum Beispiel eine neue Spalte ins Ergebnis einzufügen.
Beispiel – wir fügen eine Spalte mit dem maximalen Alter der Studenten hinzu:
SELECT name, alter,
(SELECT MAX(alter) FROM students) AS maximales_alter
FROM students;
Ergebnis:
| name | alter | maximales_alter |
|---|---|---|
| Alisa | 20 | 23 |
| Bob | 22 | 23 |
| Klark | 21 | 23 |
| Dina | 23 | 23 |
| Emilia | 22 | 23 |
- Subqueries im
FROM. Die Subquery wird als temporäre Tabelle verwendet. Das ist nützlich, wenn du erst aggregieren oder Daten transformieren willst.
Beispiel – Durchschnittsalter der Studenten in jeder Gruppe berechnen:
SELECT tmp.gruppe_id, tmp.durchschnittsalter
FROM (
SELECT gruppe_id, AVG(alter) AS durchschnittsalter
FROM students
GROUP BY gruppe_id
) AS tmp -- Wir geben der temporären Tabelle den Alias tmp
WHERE tmp.durchschnittsalter > 21;
Ergebnis:
| gruppe_id | durchschnittsalter |
|---|---|
| 2 | 22.0 |
| 3 | 23.0 |
- Subqueries in
WHEREundHAVING. Subqueries können als Bedingung verwendet werden, um Zeilen zu filtern. Das wird oft genutzt, um - zu prüfen, ob Datensätze existieren oder um Werte zu vergleichen.
Beispiel – Studenten, die älter als der Durchschnitt sind:
SELECT name, alter
FROM students
WHERE alter > (
SELECT AVG(alter)
FROM students
);
Ergebnis:
| name | alter |
|---|---|
| Bob | 22 |
| Dina | 23 |
| Emilia | 22 |
Vorteile von verschachtelten Abfragen
Mehr Flexibilität: Mit verschachtelten Abfragen kannst du mit komplexeren Datenstrukturen arbeiten.
Aufteilen der Aufgaben in Schritte: Die Logik kann in Subqueries aufgeteilt werden, was den Code lesbarer macht.
Zugriff auf Zwischendaten: Du kannst Daten "on the fly" verarbeiten, ohne temporäre Tabellen in der Datenbank anlegen zu müssen.
GO TO FULL VERSION