Lektionen des Moduls (4/4)
Eine Abfrage in einer anderen: Subabfragen
Sie haben gelernt, wie man extrahiert, filtert, gruppiert, verbindet und transformiert. Da ist eine letzte Grundidee: eine Abfrage in eine andere einfügen. Das sind Sie werden Unterabfragen genannt und sind der Schritt, mit dem Sie Fragen beantworten können wie „Wer verdient überdurchschnittlich?“ oder „Welche Abteilungen haben jemanden?“ einem Projekt zugeordnet?"_.
Die grundlegende Syntax
Eine Unterabfrage ist ein in Klammern eingeschlossener SELECT, der anstelle einer einzelnen verwendet wird
Wert oder eine Liste von Werten in einer anderen Abfrage:
-- Find who earns MORE THAN THE COMPANY AVERAGE:
SELECT first_name, last_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);Die Engine führt zuerst die Unterabfrage aus – SELECT AVG(salary) FROM employees
gibt eine einzelne Zahl zurück – und verwendet diese Zahl dann im äußeren WHERE
als hätte man es von Hand geschrieben. Das ist genau der Vorteil: Sie tun es
Sie müssen den Durchschnitt nicht im Voraus kennen, SQL berechnet ihn für Sie.
Die drei häufigsten „Typen“
1. Unterabfrage, die einen einzelnen Wert zurückgibt
Das obige Beispiel: Die Unterabfrage erzeugt eine Zeile, eine Spalte (genannt
Skalar). Sie verwenden es mit =, >, < usw.
-- Employee with the highest salary:
SELECT first_name, last_name
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);2. Unterabfrage, die eine Liste zurückgibt
Die Unterabfrage erzeugt eine Spalte, viele Zeilen. Sie verwenden es mit
IN (...):
-- Departments that have at least one employee:
SELECT name
FROM departments
WHERE id IN (SELECT DISTINCT department_id
FROM employees
WHERE department_id IS NOT NULL);3. Unterabfrage als „Tabelle“ (FROM)
Eine Unterabfrage kann auch eine Tabelle in FROM ersetzen. Es ist nützlich
Berechnen Sie Aggregate vorab und filtern oder verknüpfen Sie sie dann:
-- Departments with average salary above 40000:
SELECT d.name, medie.stipendio_medio
FROM departments AS d
JOIN (SELECT department_id, AVG(salary) AS stipendio_medio
FROM employees
GROUP BY department_id) AS medie
ON d.id = medie.department_id
WHERE medie.stipendio_medio > 40000;Unterabfrage oder JOIN? Wann welche verwenden
Oft kann das gleiche Ergebnis mit einem JOIN oder einer Unterabfrage erzielt werden.
Faustregel:
- Um Zeilen einer Tabelle basierend auf einer Eigenschaft einer anderen zu filtern
("Mitarbeiter, deren Abteilungen sind…"),
IN (subquery)ist sehr gut lesbar. - Um im Ergebnis Spalten aus mehreren Tabellen zu kombinieren, verwenden Sie
JOIN. - Um ein Aggregat zu berechnen und es als Schwellenwert zu verwenden ("über dem Durchschnitt"), ist die skalare Unterabfrage die natürliche Wahl.
In der Praxis werden Sie beides sehen: Die SQL-Engine optimiert sie oft gleich Weg. Wählen Sie die Form, die sich am besten liest.
Probieren Sie es aus
Finden Sie Vornamen (first_name), Nachnamen (last_name) und Gehalt (salary) der Mitarbeiter, die STRENG mehr als den Unternehmensdurchschnitt verdienen. Drei Spalten.
Hinweis anzeigen
Ersetzen ? mit der Unterabfrage SELECT AVG(gehalt) FROM Mitarbeiter – es wird eine einzelne Zahl zurückgegeben, die als Schwellenwert verwendet wird.
Lösung nach 3 Versuchen verfügbar
Wiederholungsübung
Listen Sie die Namen (departments.name) der Abteilungen auf, die mindestens einen Mitarbeiter haben, dessen Gehalt unbedingt über 50.000 liegt. Verwenden Sie eine Unterabfrage mit IN. Alphabetisch sortieren.
Hinweis anzeigen
Die innere Unterabfrage gibt die IDs der Abteilungen zurück, die Mitarbeiter mit einem Gehalt > 50.000 haben. Dann WHERE id IN (...) in der äußeren Abfrage.
Lösung nach 3 Versuchen verfügbar