Zurück zur Artikelliste Artikel
7 Leseminuten

Was ist eine verschachtelte Abfrage in SQL?

Haben Sie sich jemals gewünscht, eine Abfrage mit mehreren SELECT-Anweisungen erstellen zu können? Gute Nachrichten! Mit den verschachtelten Abfragen von SQL können Sie dies - und noch viel mehr - tun.

Wenn Sie sich schon eine Weile mit SQL beschäftigen (und vielleicht auch schon einige Abfragen geschrieben haben), sind Sie wahrscheinlich auf Fälle gestoßen, in denen es so aussieht, als ob Sie eine weitere SELECT-Anweisung innerhalb Ihrer Hauptanweisung benötigen. Vielleicht fragen Sie sich: "Ist es möglich, verschachtelte SELECTs in SQL zu verwenden?". Ja, das ist möglich! In diesem Artikel erkläre ich Ihnen die verschachtelte Abfrage (auch bekannt als verschachteltes SELECT) und wie Sie sie effizient einsetzen können.

Wenn Sie SQL üben wollen, schauen Sie sich unseren SQL-Praxis Reihe an. Sie bietet mehrere praktische interaktive SQL-Kurse mit Übungen zu verschachtelten SELECT-Anweisungen und anderen anspruchsvollen SQL-Funktionen.

Was ist ein verschachteltes SELECT?

Ein verschachteltes SELECT ist eine Abfrage innerhalb einer Abfrage, d.h. wenn Sie eine SELECT-Anweisung innerhalb des Haupt-SELECTs haben. Um das Konzept zu verdeutlichen, lassen Sie uns gemeinsam ein Beispiel durchgehen.

In diesem Artikel werden wir mit den Daten einer fiktiven High School arbeiten. Die Datenbank enthält drei Tabellen: students, teachers, und classes. Sie können die Tabellen unten sehen:

Students

idnameclass_idGPA
1Jack Black33.45
2Daniel White13.15
3Kathrine Star13.85
4Helen Bright23.10
5Steve May22.40

Teachers

idnamesubjectclass_idmonthly_salary
1Elisabeth GreyHistory32,500
2Robert SunLiterature[NULL]2,000
3John ChurchillEnglish12,350
4Sara ParkerMath23,000

Classes

idgradeteacher_idnumber_of_students
110321
211425
312128

Nehmen wir an, Sie möchten alle Schüler mit überdurchschnittlichen Notendurchschnitten finden. Sie kennen jedoch die durchschnittliche GPA-Punktzahl nicht. Natürlich können Sie eine Abfrage verwenden, um dies herauszufinden:

SELECT AVG(GPA)
FROM students;

Sie erhalten eine Zahl (3,19), mit der Sie die ursprüngliche Aufgabe lösen können, nämlich alle Informationen über Studenten mit einem überdurchschnittlichen Notendurchschnitt anzuzeigen:

SELECT *
FROM students
WHERE GPA > 3.19;

Aber können Sie diese Aufgabe auch in einem Schritt lösen? Ja, mit einer verschachtelten Abfrage. Das sieht folgendermaßen aus:

SELECT *
FROM students
WHERE GPA > (
	SELECT AVG(GPA)
	FROM students);

Unsere Unterabfrage hier gibt einen einzigen Wert zurück (d. h. eine Tabelle mit einer einzigen Spalte und einer einzigen Zeile). Dies ist wichtig, damit der Vergleichsoperator funktioniert. Mit der durchschnittlichen GPA-Punktzahl, die von der inneren Abfrage zurückgegeben wird, kann die äußere Abfrage die Schüler auswählen, die unsere Filterbedingung erfüllen (d.h. eine GPA-Punktzahl über dem Durchschnitt).

Und hier ist das Ergebnis:

idnameclass_idGPA
1Jack Black33.45
3Kathrine Star13.85

Der richtige Begriff für diese verschachtelte SELECT-Anweisung ist Unterabfrage. Es gibt viele verschiedene Szenarien, in denen SQL-Unterabfragen sehr hilfreich sind.

Weitere Beispiele für verschachtelte SQL-Abfragen

Zunächst einmal können Sie ein verschachteltes SELECT innerhalb der WHERE-Klausel mit Vergleichsoperatoren oder den Operatoren IN, NOT IN, ANY oder ALL einfügen. Die zweite Gruppe von Operatoren wird verwendet, wenn Ihre Unterabfrage eine Liste von Werten zurückgibt (und nicht nur einen einzelnen Wert, wie im vorherigen Beispiel):

  • Der Operator IN prüft, ob ein bestimmter Wert in der von der Unterabfrage zurückgegebenen Tabelle enthalten ist.
  • Der Operator NOT IN filtert die Zeilen heraus, die den Werten entsprechen, die nicht in der von einer Unterabfrage zurückgegebenen Tabelle enthalten sind.
  • Der Operator ANY wird mit Vergleichsoperatoren verwendet, um zu prüfen, ob einer der von der Unterabfrage zurückgegebenen Werte die Bedingung erfüllt.
  • Der Operator ALL wird auch mit Vergleichsoperatoren verwendet, um zu prüfen, ob alle von der Unterabfrage zurückgegebenen Werte die Bedingung erfüllen.

Schauen wir uns an, wie der IN Operator funktioniert. In diesem Beispiel berechnen Sie die durchschnittliche Anzahl der Schüler in Klassen, in denen der Lehrer Geschichte oder Englisch unterrichtet:

SELECT AVG(number_of_students)
FROM classes
WHERE teacher_id IN (
	SELECT id
	FROM teachers
	WHERE subject = 'English' OR subject = 'History');

Hier verwenden Sie eine Unterabfrage, um nur die Lehrer-IDs auszuwählen, die mit Lehrern für Englisch oder Geschichte übereinstimmen. Beachten Sie, dass unsere Unterabfrage eine Liste von Werten zurückgibt, d.h. eine Tabelle mit einer Spalte (id) und mehreren Zeilen, die die Bedingung der inneren Abfrage erfüllen.

In unserer äußeren Abfrage berechnen Sie dann die durchschnittliche Anzahl der Schüler nur für die Klassen, die die obige Bedingung erfüllen. Für jede teacher_id prüft der IN-Operator, ob diese ID in der von der inneren Abfrage zurückgegebenen Tabelle vorhanden ist. Dadurch wird sichergestellt, dass nur die Klassen, die diesen Lehrern entsprechen, in der Berechnung berücksichtigt werden.

Weitere Beispiele für die Verwendung der Operatoren IN, NOT IN, ANY oder ALL finden Sie in unserer Anleitung zu SQL-Unterabfragen.

Mehrere Unterabfragen in einer Anweisung

Sind Sie bereit für weitere anspruchsvolle Beispiele? Es ist tatsächlich möglich, mehrere verschachtelte SELECTs in einer Anweisung zu verwenden.

Nehmen wir an, Sie möchten alle Informationen über die Schüler der Klasse mit der höchsten Schülerzahl anzeigen. Um diese Frage zu beantworten, müssen Sie zunächst die Klasse mit der höchsten Schülerzahl finden und dann diese Klasse definieren. Schließlich müssen Sie die Informationen über die Schüler in dieser Klasse anzeigen.

Um dieses Problem zu lösen, können Sie eine Unterabfrage innerhalb einer anderen Unterabfrage verwenden:

SELECT *
FROM students
WHERE class_id = (
	SELECT id
	FROM classes
	WHERE number_of_students = (
		SELECT MAX(number_of_students)
		FROM classes));

Ziemlich praktisch, nicht wahr?

Verwendung von Unterabfragen außerhalb von WHERE

Außerdem sind Unterabfragen nicht auf die Verwendung in der WHERE-Klausel beschränkt. Sie können eine verschachtelte Abfrage zum Beispiel auch in der FROM-Klausel verwenden. Im nächsten Beispiel wird unsere Unterabfrage nicht einen einzelnen Wert, sondern eine Tabelle zurückgeben.

Wir wollen herausfinden, welcher Fachbereich dem höchsten durchschnittlichen Lehrergehalt entspricht. Dazu müssen Sie zunächst das Durchschnittsgehalt nach Fachbereich berechnen und dann anhand dieser Tabelle das höchste Durchschnittsgehalt ermitteln:

SELECT subject, MAX(salary_by_subject.avg_salary) AS max_salary
FROM (
	SELECT subject, AVG(monthly_salary) AS avg_salary
	FROM teachers
	GROUP BY subject) salary_by_subject;

Beachten Sie, dass die innere Abfrage eine Tabelle mit mehreren Zeilen und Spalten zurückgibt. Genauer gesagt, wird die Tabelle zwei Spalten haben, subject und avg_salary, um das durchschnittliche Gehalt der Lehrer auf der Grundlage ihres Hauptfachs anzuzeigen. Die Anzahl der Zeilen entspricht der Anzahl der einzelnen Fächer, die in der Schule unterrichtet werden (d.h. wie in der teachers-Tabelle). Sie müssen auch einen Alias für diese Tabelle angeben: salary_by_subject.

Die äußere Abfrage berechnet dann einfach das maximale Durchschnittsgehalt auf der Grundlage der salary_by_subject-Tabelle und gibt diesen Wert zusammen mit dem Namen des entsprechenden Fachs zurück:

subjectmax_salary
Math3,000

Wie Sie sehen können, haben die Mathematiklehrer unserer Schule das höchste durchschnittliche Monatsgehalt (3000 $).

Für einige Aufgaben muss die innere Abfrage möglicherweise Informationen aus der äußeren Abfrage verwenden. Wenn zwei Abfragen auf diese Weise miteinander verbunden sind, nennt man sie korrelierte Unterabfragen. Dies ist ein fortgeschrittenes Thema, das in unserem Leitfaden für Einsteiger zu korrelierten Unterabfragen und in diesem praktischen Tutorial zum Schreiben von korrelierten Unterabfragen sehr gut erklärt wird.

Zusätzliche Tipps zur Verwendung von verschachtelten SELECTs

SQL-Unterabfragen sind ein mächtiges Werkzeug. Sie ermöglichen es uns, Aufgaben effizienter auszuführen, da wir nur eine Abfrage statt mehrerer haben.

Behalten Sie bei der Verwendung von verschachtelten Abfragen die folgenden Punkte im Kopf:

  • Unterabfragen können einzelne Werte oder Tabellen (mit einer oder mehreren Zeilen und Spalten) zurückgeben.
  • Sie können in folgenden Fällen eine Unterabfrage einschließen:
    • In der WHERE-Klausel, um Daten zu filtern.
    • In der FROM-Klausel, um eine neue Tabelle anzugeben.
    • In der SELECT-Klausel, um eine bestimmte Spalte zu bestimmen.
    • In der HAVING-Klausel, als Gruppenselektor.
  • Unterabfragen sollten immer in Klammern () eingeschlossen werden.
  • Verschiedene Datenbankmanagementsysteme haben bestimmte Beschränkungen für die Anzahl der Unterabfrageebenen (z.B. bis zu 32 Ebenen im SQL Server). In der Praxis werden Sie jedoch selten mehr als 2-3 Ebenen von verschachtelten Abfragen haben.
  • Unterabfragen sind oft in der Berechnung ineffizient. Ich empfehle daher, verschachtelte Abfragen zu vermeiden, wenn andere Optionen zur Verfügung stehen (z. B. JOINs).

Zeit zum Üben von SQL-Unterabfragen!

Jetzt, wo Sie so viel über verschachtelte Abfragen in SQL gelernt haben, möchten Sie wahrscheinlich auch gleich damit anfangen, sie zu üben! Zum Glück haben wir eine Menge interaktiver Übungen für Sie, mit denen Sie verschiedene SQL-Unterabfragen üben können.

Zunächst einmal hat unser SQL für Anfänger Kurs einen großen Abschnitt über Unterabfragen. Schauen Sie ihn sich unbedingt an!

Wenn Sie ein wirklich sicherer Benutzer von verschachtelten Abfragen in SQL werden wollen, empfehle ich Ihnen auch unseren SQL-Praxis Kurs. Er enthält interaktive SQL-Kurse mit praktischen Übungen, um Unterabfragen und andere anspruchsvolle Konstruktionen in SQL zu üben.

Unterabfragen werden Sie definitiv zu einem viel leistungsfähigeren SQL-Anwender machen. Viel Spaß beim Lernen!