Alle Tabs der Lerneinheit (Erklärung · Subquery-Explorer · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Diese Lerneinheit wurde für typische Bachelor-Klausuren konzipiert. So prüfen wir · Fehler entdeckt? Melde ihn uns oder markiere die fragliche Stelle direkt im Text oben.
Alle Tabs der Lerneinheit (Erklärung · Subquery-Explorer · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
"Gib mir alle Studierenden, die mehr Kurse belegen als der Durchschnitt." Geht das mit einem einfachen JOIN? Nein. Du brauchst eine Subquery — eine SELECT-Abfrage innerhalb einer anderen. Klausur-Pflicht in 12/12 WInf-DB-Klausuren, weil Subqueries die Brücke zwischen einfachem SQL und komplexer Datenanalyse sind.
Klausur-Tipp: Schreib bei komplexen Subqueries die Zwischen-Ergebnisse auf einen Schmierzettel. Innere zuerst, dann äußere — Schritt für Schritt.
Anmelden, um den Fortschritt zu speichern.
Nächster Schritt
Aktives Abrufen festigt Wissen schneller als nochmal lesen.
"Gib mir alle Studierenden, die mehr Kurse belegen als der Durchschnitt." Geht das mit einem einfachen JOIN? Nein. Du brauchst eine Subquery — eine SELECT-Abfrage innerhalb einer anderen. Klausur-Pflicht in 12/12 WInf-DB-Klausuren, weil Subqueries die Brücke zwischen einfachem SQL und komplexer Datenanalyse sind.
Eine Subquery ist eine SELECT-Abfrage, deren Ergebnis als Wert oder Tabelle in eine andere Abfrage eingebaut wird.
3 typische Verwendungs-Orte:
Tabellen:
Studierende:
| MatrNr | Name | Semester |
|---|---|---|
| 1001 | Müller | 3 |
| 1002 | Schulz | 5 |
| 1003 | Klein | 3 |
Belegungen:
| MatrNr | KursID |
|---|---|
| 1001 | DB1 |
| 1001 | INF |
| 1002 | DB1 |
Frage: Welche Studierenden haben DB1 belegt?
SELECT Name
FROM Studierende
WHERE MatrNr IN (
SELECT MatrNr FROM Belegungen WHERE KursID = 'DB1'
);
So liest du das:
Frage: Welche Studierenden haben mindestens eine Belegung?
SELECT Name
FROM Studierende s
WHERE EXISTS (
SELECT 1 FROM Belegungen b WHERE b.MatrNr = s.MatrNr
);
Das ist eine korrelierte Subquery: die innere Query referenziert die äußere (s.MatrNr). Für jede Zeile der äußeren Query wird die innere neu ausgewertet. Resultat: Müller, Schulz (nicht Klein, der hat keine Belegung).
Performance-Hinweis: Korrelierte Subqueries sind oft langsam, weil sie einmal pro äußerer Zeile laufen. Moderne Optimizer können sie aber meist in Joins umschreiben.
Frage: Pro Studi: wie viele Kurse belegt?
SELECT
Name,
(SELECT COUNT(*) FROM Belegungen b WHERE b.MatrNr = s.MatrNr) AS Anzahl
FROM Studierende s;
Die Subquery liefert einen Skalar (genau einen Wert) pro Zeile. Ergebnis:
| Name | Anzahl |
|---|---|
| Müller | 2 |
| Schulz | 1 |
| Klein | 0 |
Wichtig:
NOT INundNOT EXISTSsind NICHT immer äquivalent, wenn NULL-Werte im Spiel sind.
NOT IN (SELECT ... mit NULL) ergibt leer, weil "x ≠ NULL" → UNKNOWN → ausgeschlossen.
NOT EXISTS behandelt das richtig.
Faustregel: Wenn die Subquery NULL enthalten könnte → NOT EXISTS nehmen, nicht NOT IN.
Schau, wie eine verschachtelte Query von innen nach außen ausgewertet wird:
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
- 3 Verwendungen auswendig: WHERE x IN (...), WHERE EXISTS (...), SELECT (...) AS alias.
- Lese von innen nach außen. Erst innere Query auswerten, dann äußere mit dem Ergebnis.
- Korrelierte Subquery erkennen: wenn die innere Query eine Spalte der äußeren referenziert. Klassiker mit EXISTS.
- NOT IN bei NULL-Werten ist gefährlich. Lieber NOT EXISTS verwenden.
- Skalare Subquery muss genau einen Wert liefern (sonst Laufzeit-Fehler). Bei Aggregaten (COUNT, MAX, ...) immer der Fall.
1. Klammern vergessen. Subqueries MÜSSEN in runden Klammern stehen — kein "WHERE x IN SELECT ..." ohne Klammern.
2. Mehrere Zeilen in Skalar-Subquery. SELECT (SELECT name FROM ...) FROM ... — wenn die innere mehrere Zeilen liefert, knallt es zur Laufzeit. Bei "single row expected" prüfe, ob du WHERE-Bedingung vergessen hast.
3. Subquery vs. JOIN — wann was? JOIN ist meist schneller bei "x IN (...)". Subquery ist nötig bei aggregierten Vergleichen (z.B. "über dem Durchschnitt") oder Existenz-Tests.
4. SELECT-Subquery (Skalar) und WHERE-Subquery (IN) verwechseln. Skalare brauchen genau einen Wert, IN braucht eine Spalte. Falsche Stelle → SQL-Fehler.
Klicke ein Szenario, dann gehe Schritt für Schritt durch: erst die innere Query, dann die äußere. Zwischen-Ergebnis wird hervorgehoben.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Klausur-Tipp: Schreib bei komplexen Subqueries die Zwischen-Ergebnisse auf einen Schmierzettel. Innere zuerst, dann äußere — Schritt für Schritt.
6 Aufgaben zu IN, EXISTS, NOT-Varianten und Skalar-Subqueries.
Klausurfragen mit Lösungen (6)
Antwort: Von innen nach außen
Erklärung: Von innen nach außen: erst innere Query ausführen, das Ergebnis in die äußere Query einsetzen. So entwickelt der Optimizer den Plan, und so verstehst du auch in der Klausur was passiert.
Antwort: SELECT Name FROM Stud WHERE MatrNr IN (SELECT MatrNr FROM Beleg)
Erklärung: IN-Subquery: ergibt MatrNrs aus Belegungen, dann gibt Stud-Zeilen mit diesen MatrNrs. Alternative: WHERE EXISTS (SELECT 1 FROM Beleg b WHERE b.MatrNr=s.MatrNr).
Antwort: Eine Subquery, deren innere Query Spalten der äußeren Query referenziert
Erklärung: Korreliert = die innere Query bezieht sich auf eine Variable der äußeren Query. Wird einmal pro äußerer Zeile ausgewertet — kann teuer sein, aber moderne Optimizer können oft in Joins umschreiben.
Antwort: Falsch
Erklärung: FALSCH. NOT IN mit NULL-Wert in der Subquery ergibt 'unknown' für jeden Vergleich und filtert ALLES aus. NOT EXISTS prüft nur Existenz und ist NULL-sicher. Klausur-Klassiker.
Typ: Wahr/Falsch
Antwort: Skalare Subquery in SELECT
Erklärung: Skalare Subquery in SELECT: SELECT (SELECT COUNT(*) FROM Beleg b WHERE b.MatrNr = s.MatrNr) FROM Stud s. Muss genau einen Wert pro Zeile liefern, sonst Laufzeit-Fehler.
Zuordnungen:
Erklärung: Die 4 wichtigsten Subquery-Patterns. ANY/SOME ist äquivalent zu IN bei =, kann aber mit anderen Operatoren (>, <) kombiniert werden für Bereichs-Vergleiche.
Typ: Zuordnung
Klausurfragen mit Lösungen (6)
Antwort: SELECT MatrNr FROM Beleg GROUP BY MatrNr HAVING COUNT(*) > (SELECT AVG(c) FROM (SELECT COUNT(*) AS c FROM Beleg GROUP BY MatrNr) sub)
Erklärung: Klausur-Klassiker mit doppelt verschachtelter Subquery: innen pro Studi zählen (COUNT(*) GROUP BY MatrNr), dann den AVG dieser Zahlen, dann HAVING-Filter. Direkte Aggregat-Verschachtelungen wie AVG(COUNT(*)) sind in Standard-SQL nicht erlaubt.
Antwort: IN und EXISTS
Erklärung: WHERE x IN (SELECT y FROM ...) ist meist äquivalent zu WHERE EXISTS (SELECT 1 FROM ... WHERE y=x). Beide testen Existenz mit Wert-Gleichheit. NULL-Verhalten unterscheidet sich nur bei NOT-Varianten.
Richtige Reihenfolge:
Erklärung: Innere Query immer zuerst: filtere → projeziere → das Ergebnis wird zur Liste für IN. Dann äußere Query: WHERE-Filter → SELECT.
Typ: Reihenfolge
Antwort: Wahr
Erklärung: Wahr — semantisch. Optimizer können das in Joins umschreiben, sodass die tatsächliche Ausführung schneller wird. Aber konzeptionell: ja, einmal pro äußerer Zeile.
Typ: Wahr/Falsch
Antwort: WHERE EXISTS (...)
Erklärung: EXISTS testet nur 'gibt es mindestens eine Zeile?' — NULL ist nicht relevant, weil keine Wert-Vergleiche stattfinden. NOT EXISTS ist auch sicher. IN/NOT IN haben NULL-Probleme bei Vergleichen.
Lösungen pro Lücke:
Erklärung: Die Standard-Subquery-Operatoren plus die NULL-Falle. Klausur-Pflichtwissen.
Typ: Lückentext