Stell dir vor, du bist Analyst an einer Uni (wir bauen ja gerade eine Uni-Datenbank, erinnerst du dich?). Man hat dich gebeten, nicht nur die Studenten und ihre Noten auszugeben, sondern auch eine Spalte mit der Maximalnote in der Gruppe hinzuzufügen, damit man die Ergebnisse easy vergleichen kann. Wie löst man das? Natürlich mit Subqueries im SELECT!
Eine Subquery im SELECT erlaubt es dir, Werte direkt beim Ausführen des Hauptqueries zu berechnen. Das ist cool, weil du aggregierte Berechnungen, komplexe Filter und sogar andere Datensammlungen in einem einzigen Query kombinieren kannst.
Basics von verschachtelten Queries im SELECT
Eine Subquery im SELECT funktioniert wirklich so, wie es klingt: Du fügst das Ergebnis eines SELECT in ein anderes ein. Damit kannst du für jede Zeile im Ergebnis zusätzliche Werte berechnen.
Hier ein einfaches Beispiel. Angenommen, wir haben eine Tabelle students mit folgender Struktur:
| student_id | name | group_id |
|---|---|---|
| 1 | Linda | 101 |
| 2 | Otto | 102 |
| 3 | Anna | 101 |
Und die Tabelle grades:
| grade_id | student_id | grade |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 2 | 3 |
| 4 | 3 | 5 |
| 5 | 3 | 4 |
Beispiel 1: Maximalnote in der Gruppe hinzufügen
Aufgabe: Gib die Namen der Studenten, ihre Noten und die Maximalnote in der Gruppe aus, damit man sieht, wie sehr die Noten jedes Studenten von den besten Ergebnissen der Gruppe abweichen.
SQL-Code:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT MAX(grade) -- diese Query gibt genau einen Wert zurück
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS max_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Was passiert hier:
- Für jeden Studenten holen wir seinen Namen und seine Note (
s.name,g.grade). SELECT MAX(grade)— das ist die Subquery, die die Maximalnote innerhalb der Gruppe des Studenten zurückgibt.- Die Subquery wird für jede Zeile des Hauptqueries ausgeführt und nutzt die Bedingung
WHERE students.group_id = s.group_id, um die Auswahl auf eine Gruppe zu beschränken.
Beispiel 2: Durchschnittsnote pro Gruppe
Willst du noch nützlicher für Analysten sein? Lass uns nicht nur die Maximalnote, sondern auch die Durchschnittsnote der Gruppe ausgeben.
SQL-Code:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT AVG(grade)
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS avg_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Jetzt:
- Statt
MAX()benutzen wirAVG(), um die Durchschnittsnote in der Gruppe zu berechnen. - So bekommst du eine "Live"-Datenanalyse.
Einschränkungen und Tipps
Subqueries im SELECT sind mächtig, aber du solltest sie mit Bedacht einsetzen:
- Performance. Jede Subquery wird für jede Zeile des Hauptqueries ausgeführt. Das kann den SQL-Query langsam machen, wenn die Tabellen groß sind. Zum Beispiel: Wenn es 1000 Studenten gibt, wird die Subquery 1000 Mal ausgeführt!
- Indizes. Um solche Queries schneller zu machen, solltest du die Spalten, die in den
WHERE-Bedingungen der Subquery vorkommen, richtig indizieren. - Lesbarkeit. Vermeide zu viel Verschachtelung. Wenn die Subqueries zu kompliziert werden, überleg, ob du sie in
FROMverschieben oder temporäre Tabellen nutzen kannst.
Beispiele für die Nutzung
Schauen wir uns noch ein paar interessante Cases an.
Beispiel 3: Anzahl der Kurse pro Student
Wir geben eine Tabelle aus, in der für jeden Studenten die Anzahl der Kurse angezeigt wird, für die er eingeschrieben ist. Die Tabelle enrollments ist über student_id mit den Studenten verbunden:
| student_id | course_id |
|---|---|
| 1 | 201 |
| 1 | 202 |
| 2 | 201 |
| 3 | 203 |
SQL-Code:
SELECT
s.name AS student_name,
(
SELECT COUNT(*)
FROM enrollments
WHERE enrollments.student_id = s.student_id
) AS course_count
FROM
students s;
Hier zählt die Subquery die Anzahl der Einträge in der Tabelle enrollments für jeden Studenten.
Beispiel 4: "Ausgezeichnet"-Flag für jeden Studenten
Wir zeigen, ob ein Student ein "Ausgezeichnet"-Schüler ist. Das Kriterium: Alle seine Noten sind 5.
SQL-Code:
SELECT
s.name AS student_name,
(
SELECT CASE
WHEN MIN(g.grade) = 5 THEN 'Ausgezeichnet'
ELSE 'Nicht ausgezeichnet'
END
FROM grades g
WHERE g.student_id = s.student_id
) AS status
FROM
students s;
Hier wird ein verschachteltes CASE verwendet, um den Status "Ausgezeichnet" nur den Studenten zu geben, die alle Noten auf 5 haben.
Optimierung von Subqueries im SELECT
Wir haben schon erwähnt, dass Performance ein Problem sein kann. Hier ein paar Tipps, wie du das verbessern kannst:
- Benutze Indizes. Wenn Subqueries Daten filtern, stell sicher, dass es Indizes auf den verwendeten Spalten gibt.
- Ergebnisse cachen. Manchmal ist es sinnvoll, Subqueries in Views (
VIEW) oder temporäre Tabellen auszulagern. - Weniger Verschachtelung. Übertreib es nicht mit zu vielen Subqueries, wenn es auch einfacher geht.
Subqueries im SELECT eröffnen dir viele Möglichkeiten für Berechnungen und Datenanalyse. Auch wenn sie ressourcenhungrig sein können, macht ihr richtig optimierter Einsatz SQL viel ausdrucksstärker und flexibler. Also, probier ruhig rum und finde deinen eigenen Weg, Queries zu verbessern!
GO TO FULL VERSION