Zurück zur Artikelliste Artikel
8 Leseminuten

5 Beispiele für SQL-Unterabfragen

SQL-Unterabfragen sind grundlegende Werkzeuge, wenn Sie effektiv mit relationalen Datenbanken kommunizieren möchten. In diesem Artikel finden Sie fünf Beispiele für Unterabfragen, die zeigen, wie Sie skalare, mehrzeilige und korrelierte Unterabfragen in den WHERE-, FROM/JOIN- und SELECT-Klauseln verwenden können.

Eine Unterabfrage oder verschachtelte Abfrage ist eine Abfrage, die innerhalb einer anderen SQL-Abfrage platziert wird. Wenn Sie Informationen aus einer Datenbank abfragen, kann es notwendig sein, eine Unterabfrage in die Klausel SELECT, FROM, JOIN oder WHERE aufzunehmen. Sie können jedoch auch Unterabfragen verwenden, wenn Sie die Datenbank aktualisieren (d. h. in den Anweisungen INSERT, UPDATE und DELETE ).

Es gibt mehrere Arten von SQL-Unterabfragen:

  • Skalare Unterabfragen geben einen einzigen Wert oder genau eine Zeile und genau eine Spalte zurück.
  • Mehrzeilige Unterabfragen geben entweder zurück:
    • eine Spalte mit mehreren Zeilen (d. h. eine Liste von Werten) oder
    • Mehrere Spalten mit mehreren Zeilen (z. B. Tabellen).
  • Korrelierte Unterabfragen, bei denen sich die innere Abfrage auf Informationen stützt, die aus der äußeren Abfrage stammen.

Sie können an anderer Stelle mehr über die verschiedenen Arten von SQL-Unterabfragen lesen; hier möchte ich mich auf Beispiele konzentrieren. Wie wir alle wissen, ist es immer einfacher, neue Konzepte anhand von realen Anwendungsfällen zu begreifen. Fangen wir also an.

5 Beispiele für Unterabfragen in SQL

Nehmen wir an, wir betreiben eine Kunstgalerie. Wir haben eine Datenbank mit vier Tabellen: paintings, artists, collectors, und sales. Sie können die in jeder Tabelle gespeicherten Daten unten sehen.

paintings
idnameartist_idlisted_price
11Miracle1300.00
12Sunshine1700.00
13Pretty woman22800.00
14Handsome man22300.00
15Barbie3250.00
16Cool painting35000.00
17Black square #1000350.00
18Mountains41300.00

artists
idfirst_namelast_name
1ThomasBlack
2KateSmith
3NataliWein
4FrancescoBenelli

collectors
idfirst_namelast_name
101BrandonCooper
102LauraFisher
103ChristinaBuffet
104SteveStevenson

sales
iddatepainting_idartist_idcollector_idsales_price
10012021-11-011321042500.00
10022021-11-101421022300.00
10032021-11-10111102300.00
10042021-11-151631034000.00
10052021-11-22153103200.00
10062021-11-2217310350.00

Lassen Sie uns nun diese Daten mithilfe von SQL-Abfragen mit verschiedenen Arten von Unterabfragen untersuchen.

Beispiel 1 - Skalare Unterabfrage

Wir beginnen mit einem einfachen Beispiel: Wir möchten Gemälde auflisten, deren Preis über dem Durchschnitt liegt. Im Grunde genommen möchten wir die Namen der Gemälde zusammen mit den aufgelisteten Preisen erhalten, aber nur für diejenigen, die mehr als der Durchschnitt kosten. Das bedeutet, dass wir zunächst diesen Durchschnittspreis ermitteln müssen; hier kommt die skalare Unterabfrage ins Spiel:

SELECT name, listed_price
FROM paintings
WHERE listed_price > (
    SELECT AVG(listed_price)
    FROM paintings
);

Unsere Unterabfrage befindet sich in der WHERE -Klausel, wo sie die Ergebnismenge auf der Grundlage des Listenpreises filtert. Diese Unterabfrage gibt einen einzigen Wert zurück: den Durchschnittspreis pro Gemälde für unsere Galerie. Jeder aufgelistete Preis wird mit diesem Wert verglichen, und nur die Gemälde, deren Preis über dem Durchschnitt liegt, werden in die endgültige Ausgabe aufgenommen:

namelisted_price
Pretty woman2800.00
Handsome man2300.00
Cool painting5000.00

Wenn Ihnen dies etwas kompliziert erscheint, sollten Sie sich unseren interaktiven SQL für Anfänger Kurs besuchen und Ihre grundlegenden SQL-Kenntnisse auffrischen.

Beispiele 2 - Mehrzeilige Unterabfrage

Sehen wir uns nun Unterabfragen an, die eine Spalte mit mehreren Zeilen zurückgeben. Diese Unterabfragen werden oft in die WHERE Klausel aufgenommen, um die Ergebnisse der Hauptabfrage zu filtern.

Angenommen, wir möchten alle Sammler auflisten, die Gemälde aus unserer Galerie gekauft haben. Mit einer mehrzeiligen Unterabfrage können wir die erforderliche Ausgabe erhalten. Insbesondere können wir eine innere Abfrage verwenden, um alle IDs der Sammler aufzulisten, die in der Tabelle sales auflisten - das sind die IDs der Sammler, die mindestens einen Kauf in unserer Galerie getätigt haben. In der äußeren Abfrage fragen wir dann den Vor- und Nachnamen aller Sammler ab, deren ID in der Ausgabe der inneren Abfrage enthalten ist. Hier ist der Code:

SELECT first_name, last_name
FROM collectors
WHERE id IN (
    SELECT collector_id
    FROM sales
);

Und hier ist die Ausgabe:

first_namelast_name
LauraFisher
ChristinaBuffet
SteveStevenson

Interessanterweise könnten wir das gleiche Ergebnis ohne eine Unterabfrage erhalten, indem wir eine INNER JOIN (oder einfach JOIN) verwenden. Dieser Verknüpfungstyp gibt nur Datensätze zurück, die in beiden Tabellen gefunden werden können. Wenn wir also die Tabellen collectors und die sales verknüpfen, erhalten wir eine Liste von Collectors mit entsprechenden Datensätzen in der sales Tabelle. Hinweis: Ich habe hier auch das Schlüsselwort DISTINCT verwendet, um Duplikate aus der Ausgabe zu entfernen.

Hier ist die Abfrage:

SELECT DISTINCT collectors.first_name, collectors.last_name
FROM collectors
JOIN sales
  ON collectors.id = sales.collector_id;

Mehr über die Wahl von Subquery vs. JOIN können Sie an anderer Stelle in unserem Blog lesen.

Beispiel 3 - Mehrzeilige Unterabfrage mit mehreren Spalten

Wenn eine Unterabfrage eine Tabelle mit mehreren Zeilen und mehreren Spalten zurückgibt, befindet sich diese Unterabfrage normalerweise in der FROM oder JOIN Klausel. Auf diese Weise können Sie eine Tabelle mit Daten abrufen, die in der Datenbank nicht ohne weiteres verfügbar sind (z. B. gruppierte Daten), und diese Tabelle dann gegebenenfalls mit einer anderen Tabelle aus Ihrer Datenbank verknüpfen.

Nehmen wir an, wir möchten die Gesamtsumme der Verkäufe für jeden Künstler sehen, der mindestens ein Bild in unserer Galerie verkauft hat. Wir können mit einer Unterabfrage beginnen, die auf die Tabelle sales Tabelle zurückgreift und den Gesamtbetrag der Verkäufe für jede Künstler-ID berechnet. In der äußeren Abfrage kombinieren wir dann diese Informationen mit den Vor- und Nachnamen der Künstler, um die gewünschte Ausgabe zu erhalten:

SELECT
  artists.first_name, 
  artists.last_name, 
  artist_sales.sales
FROM artists
JOIN (
    SELECT artist_id, SUM(sales_price) AS sales
    FROM sales
    GROUP BY artist_id
  ) AS artist_sales
  ON artists.id = artist_sales.artist_id;

Wir weisen der Ausgabe unserer Unterabfrage einen aussagekräftigen Alias zu (artist_sales). Auf diese Weise können wir in der äußeren Abfrage bei der Auswahl der Spalte aus dieser Tabelle und bei der Definition der Verknüpfungsbedingung in der ON Klausel leicht darauf verweisen. Hinweis: Datenbanken geben einen Fehler aus, wenn Sie keinen Alias für die Ausgabe Ihrer Unterabfrage angeben.

Hier ist das Ergebnis der Abfrage:

first_namelast_namesales
ThomasBlack300
KateSmith4800
NataliWein4250

Mit einer kurzen SQL-Abfrage konnten wir also die Gesamtverkäufe für jeden Künstler auf der Grundlage der Rohdaten aus einer Tabelle berechnen (sales) zu berechnen und diese Ausgabe dann mit den Daten einer anderen Tabelle (artists).

Unterabfragen können sehr leistungsfähig sein, wenn wir Informationen aus mehreren Tabellen kombinieren müssen. Schauen wir uns an, was wir sonst noch mit Unterabfragen machen können.

Beispiel 4 - Korrelierte Unterabfrage

Das folgende Beispiel zeigt, wie Unterabfragen:

  • in der SELECT-Klausel verwendet werden können, und
  • korreliert werden können (d. h. die Haupt- oder äußere Abfrage stützt sich auf Informationen, die aus der inneren Abfrage stammen).

Wir möchten für jeden Sammler die Anzahl der über unsere Galerie gekauften Gemälde berechnen. Um diese Frage zu beantworten, können wir eine Unterabfrage verwenden, die die Anzahl der von jedem Sammler gekauften Gemälde zählt. Hier ist die gesamte Abfrage:

SELECT
  first_name, 
  last_name,
  (
    SELECT count(*) AS paintings
    FROM sales
    WHERE collectors.id = sales.collector_id
  )
FROM collectors;

Beachten Sie, dass die innere Abfrage in diesem Beispiel tatsächlich für jede Zeile der Tabelle collectors ausgeführt wird:

  • Die Unterabfrage befindet sich in der SELECT -Klausel, weil wir eine zusätzliche Spalte mit der Anzahl der vom entsprechenden Sammler gekauften Gemälde haben möchten.
  • Für jeden Datensatz der Tabelle collectors berechnet die innere Unterabfrage für jeden Datensatz der Tabelle die Gesamtzahl der von einem Sammler erworbenen Gemälde mit der entsprechenden ID.

Hier ist die Ausgabe:

first_namelast_namepaintings
BrandonCooper0
LauraFisher2
ChristinaBuffet3
SteveStevenson1

Wie Sie sehen, ist die Ausgabe der Unterabfrage (d. h. die Anzahl der Gemälde) für jeden Datensatz unterschiedlich und hängt von der Ausgabe der äußeren Abfrage (d. h. dem entsprechenden Sammler) ab. Wir haben es hier also mit einer korrelierten Unterabfrage zu tun.

Lesen Sie diesen Leitfaden, wenn Sie wissen möchten, wie man korrelierte Unterabfragen in SQL schreibt. Lassen Sie uns nun ein weiteres Beispiel für eine korrelierte Unterabfrage betrachten.

Beispiel 5 - Korrelierte Unterabfrage

Diesmal wollen wir die Vor- und Nachnamen der Künstler anzeigen, die in unserer Galerie keine Verkäufe getätigt haben. Versuchen wir, diese Aufgabe mit einer korrelierten Unterabfrage in der WHERE -Klausel zu erfüllen:

SELECT first_name, last_name
FROM artists
WHERE NOT EXISTS (
  SELECT *
  FROM sales
  WHERE sales.artist_id = artists.id
);

In dieser Abfrage geht Folgendes vor sich:

  • Die äußere Abfrage listet grundlegende Informationen zu den Künstlern auf, indem sie zunächst prüft, ob es entsprechende Datensätze in der Tabelle sales
  • Die innere Abfrage sucht nach Datensätzen, die der Künstler-ID entsprechen, die gerade von der äußeren Abfrage geprüft wird.
  • Wenn es keine entsprechenden Datensätze gibt, werden der Vorname und der Nachname des entsprechenden Künstlers zur Ausgabe hinzugefügt:
first_namelast_name
FrancescoBenelli

In unserem Beispiel haben wir nur einen Künstler, der noch keine Verkäufe hat. Hoffentlich wird er bald einen haben.

Es ist an der Zeit, SQL-Unterabfragen zu üben!

In diesem Artikel habe ich mehrere Beispiele für SQL-Unterabfragen behandelt, um Ihnen ein allgemeines Verständnis dafür zu vermitteln, wie Unterabfragen in SQL genutzt werden können. Oftmals können jedoch Common Table Expressions (CTEs) besser als Subqueries eingesetzt werden.

Wenn Sie SQL-Unterabfragen und andere grundlegende SQL-Themen üben möchten, besuchen Sie unseren SQL für Anfänger interaktiven Kurs. Er enthält 129 Programmieraufgaben zum Abfragen mehrerer Tabellen, zum Aggregieren und Gruppieren von Daten, zum Verbinden von Tabellen, zum Schreiben von Unterabfragen und vieles mehr.

Möchten Sie ein SQL-Meister werden? Schauen Sie sich unseren Lernkurs SQL von A bis Z an. Er geht über die Grundlagen hinaus und umfasst 7 interaktive Kurse zu den Themen Standard-SQL-Funktionen, SQL-Datenmanipulationssprache (DML), grundlegende SQL-Berichte, Fensterfunktionen, allgemeine Tabellenausdrücke (CTEs) und GROUP BY-Erweiterungen.

Vielen Dank fürs Lesen und viel Spaß beim Lernen!