Typische Aufgabe aus dem Arbeitsalltag eines Informatikers: Du möchtest alle Kunden finden, deren Umsatz über dem Durchschnitt liegt. Wie würdest du das in SQL lösen? Genau hier kommt das Konzept der Subquery ins Spiel. Eine Subquery ist eine „Abfrage in einer Abfrage“ – eine geschachtelte SELECT-Anweisung, die es dir ermöglicht, Zwischenergebnisse zu berechnen und diese in der Hauptabfrage zu verwenden.
In diesem Artikel wirst du die Grundlagen von Subqueries kennenlernen, verstehen, wie sie funktionieren, und sehen, wann sie besonders sinnvoll eingesetzt werden können. Dabei helfen dir praxisnahe Beispiele, um das Konzept greifbar zu machen.
Was ist eine Subquery?
Eine Subquery ist eine SQL-Abfrage, die innerhalb einer anderen Abfrage eingebettet ist. Das bedeutet, dass du in einer Hauptabfrage eine weitere SELECT-Anweisung verschachtelst, um Zwischenergebnisse zu ermitteln, die dann in der äußeren Abfrage verwendet werden.
Subqueries können in verschiedenen Teilen einer SQL-Anweisung auftreten, am häufigsten jedoch in der WHERE-Klausel. Sie können aber auch in FROM, SELECT, HAVING oder sogar innerhalb von JOIN-Klauseln verwendet werden.
Eine einfache Analogie ist ein Hilfsrechner, der für die Hauptabfrage Zwischenergebnisse berechnet, die dann weiterverarbeitet werden.
Beispiel einer einfachen Subquery:
SELECT name
FROM customers
WHERE revenue > (SELECT AVG(revenue) FROM customers);
Arten von Subqueries
Subqueries lassen sich nach verschiedenen Kriterien unterscheiden, vor allem nach dem Rückgabewert und der Abhängigkeit von der äußeren Abfrage.
Nach Rückgabewert:
| Typ | Beschreibung | Beispiel-Klausel |
|---|---|---|
| Skalare Subquery | Gibt einen einzelnen Wert zurück. | WHERE salary > (SELECT ...) |
| Mehrzeilige Subquery | Gibt mehrere Werte zurück. | WHERE id IN (SELECT ...) |
| Tabellarische Subquery | Gibt eine ganze Tabelle zurück. | FROM (SELECT ...) AS sub |
Nach Abhängigkeit:
- Korrelierte Subquery: Bezieht sich auf Daten der äußeren Abfrage. Sie wird für jede Zeile der äußeren Abfrage neu ausgeführt.
Beispiel:WHERE EXISTS (SELECT ... WHERE outer.id = inner.id) - Nicht-korrelierte Subquery: Läuft unabhängig von der äußeren Abfrage und wird nur einmal ausgeführt.
Typische Anwendungsfälle (Wann ist sie sinnvoll?)
Fall 1: Vergleich mit Aggregatwerten
Problem: Zeige alle Produkte, die teurer als der Durchschnitt sind.
Lösung:
SELECT product_name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products);
Fall 2: Dynamische Filterung mit IN oder NOT IN
Problem: Welche Kunden haben noch nie bestellt?
Lösung:
SELECT customer_id
FROM customers
WHERE customer_id NOT IN (SELECT DISTINCT customer_id FROM orders);
Fall 3: Korrelierte Subqueries für zeilenweise Prüfung
Problem: Finde alle Mitarbeiter, die mehr als ihr Team-Durchschnitt verdienen.
Lösung:
SELECT employee_id, salary, team_id
FROM employees e1
WHERE salary > (SELECT AVG(salary)
FROM employees e2
WHERE e1.team_id = e2.team_id);
Fall 4: Tabellarische Subqueries als Datenquelle
Problem: Berechne den monatlichen Umsatz aus einer Detailtabelle.
Lösung:
SELECT month, SUM(sales)
FROM (SELECT DATE_TRUNC('month', order_date) AS month, amount AS sales
FROM orders) AS sub
GROUP BY month;
Vorteile vs. Nachteile
Vorteile:
- Lesbarkeit: Komplexe Logik wird in Teilschritte zerlegt, was den Code übersichtlicher macht.
- Flexibilität: Subqueries ersetzen manuelle Zwischenschritte wie temporäre Tabellen.
- Präzision: Ideal für Einzelwertvergleiche oder Existenzprüfungen mit
EXISTS.
Nachteile & Risiken:
- Performance: Korrelierte Subqueries können langsam sein, da sie pro Zeile der äußeren Abfrage ausgeführt werden.
- Alternativen: Manchmal sind
JOIN-Operationen oderCTEs (Common Table Expressions) effizienter. - Debugging: Verschachtelte Queries sind oft schwerer zu testen und zu verstehen.
Faustregel: Verwende eine Subquery, wenn sie klarer und kürzer als ein JOIN ist – aber überprüfe immer die Performance.
Best Practices
- Vermeide korrelierte Subqueries, wenn eine
JOIN-basierte Lösung ähnlich effizient ist. - Nutze
EXISTSstattIN, wenn du nur auf Existenz prüfen möchtest – das ist oft performanter. - Setze bei tiefen Verschachtelungen lieber
CTEs (Common Table Expressions) ein, um die Lesbarkeit zu erhöhen:WITH avg_sales AS (SELECT AVG(amount) FROM orders) SELECT * FROM products WHERE price > (SELECT * FROM avg_sales); - Teste die Performance deiner Queries mit Tools wie
EXPLAINin PostgreSQL oderEXPLAIN PLANin Oracle.
Fazit: Mächtiges Werkzeug für komplexe Anforderungen
Subqueries sind ein mächtiges Werkzeug, um komplexe Filterungen, Aggregationen oder Vergleiche in SQL umzusetzen. Sie eignen sich besonders gut für:
- Einzelwertvergleiche
- Dynamische Listen mit
INoderNOT IN - Existenzprüfungen mit
EXISTS
Allerdings solltest du immer abwägen zwischen Lesbarkeit und Performance. Bei großen Datenmengen sind oft CTEs oder JOINs die bessere Wahl.
Von SQL zu Power BI/Tableau – so funktioniert der Datenfluss
In der modernen Datenanalyse spielen SQL und BI-Tools wie Power...
Artikel lesenDenormalisierung: Wenn die dritte Normalform zu langsam ist
Die relationale Datenbanktheorie lehrt uns: Normalisierung ist der Schlüssel zu...
Artikel lesenEXPLAIN: Wie du SQL-Abfragen analysierst und optimierst
Datenbanken sind das Herzstück vieler Anwendungen und Systeme. Je größer...
Artikel lesenINNER JOIN in SQL: So verbindest du Tabellen effizient
90 % aller SQL-Datenabfragen benötigen JOINs – doch der INNER...
Artikel lesen