## Subquery: Innere Abfragen

In eine SELECT-Anweisung kann eine zweite SELECT-Anweisung (Subquery (subquery)) eingeschlossen werden. Durch die Subquery wird ein Wert oder eine Menge von Werten als Teil der Hauptanweisung erzeugt.

### Voraussetzungen

Sie benötigen die Demo-Daten für das SQL-Tutorial.

Starten Sie das Query Tool SQL Studio als Datenbankadministrator MONA mit dem Kennwort RED und melden Sie sich an die Demo-Datenbankinstanz DEMODB an.

### Beispiele

SELECT name, zip
FROM hotel.customer
WHERE zip = (SELECT MAX(zip) FROM hotel.customer)

Anzeige des Kunden mit der grössten Postleitzahl

Ergebnis

NAME | ZIP
Doe | 97213

Siehe auch:

SQL-Referenzhandbuch, Vergleichsprädikat (comparison_predicate)

SELECT hno, name, zip
FROM hotel.hotel
WHERE zip IN(SELECT zip FROM hotel.customer WHERE title = 'Mrs')

Anzeige der Hotels, die in Orten liegen, in denen auch weibliche Kunden wohnen

Ergebnis

HNO | NAME | ZIP
10 | Congress | 20005

Siehe auch:

SQL-Referenzhandbuch, IN-Prädikat (in_predicate)

SELECT hno, name
FROM hotel.hotel
WHERE name = ANY(SELECT name FROM hotel.city)

Anzeige der Hotels, die dieselben Namen haben wie irgendwelche Orte in der Ortstabelle. Die innere Abfrage ermittelt die Ortsnamenliste, mit der die Hotelnamen verglichen werden.

Ergebnis

HNO | NAME
20 | Long Island
120 | Long Beach

SELECT cno, name
FROM hotel.customer
WHERE cno = ANY(SELECT cno FROM hotel.reservation WHERE arrival > '2005-01-01')

Anzeige der Kunden, die alle Buchungen ab einem vorgegebenen Datum getätigt haben

Ergebnis

CNO | NAME
3600 | Smith
3900 | Howe

Verwenden Sie ANY, wenn die Subquery mehr als einen Wert ergibt und das in der Bedingung der WHERE-Klausel berücksichtigt werden soll, die normalerweise genau einen Wert verlangt.

Siehe auch:

SQL-Referenzhandbuch, Mengenvergleichsprädikat (quantified_predicate)

### Correlated Subquery

Mit Hilfe von Correlated Subqueries lassen sich Bedingungen zur Zeilenauswahl formulieren, die nicht für alle Zeilen einer Tabelle, sondern nur für Gruppen von Zeilen gelten sollen.

Subqueries werden nur einmal ausgewertet. Correlated Subqueries hingegen werden für jede Zeile der äußeren Tabelle ausgewertet, bei geschachtelten Subqueries von innen nach außen.

SELECT hno, type, price
FROM hotel.room room_table
WHERE price =
(SELECT MAX(price) FROM hotel.room WHERE type = room_table.type)

Anzeige der Hotels (in Form der Hotelnummer), deren Zimmer in den einzelnen Typen (Einzel, Doppel, Suite) den höchsten Preis haben

Da in diesem Beispiel in der äußeren SELECT-Anweisung und in der Subquery die gleiche Tabelle angesprochen wird, muss ein Referenzname (room_table) vergeben werden. Eine Zeile aus dem Ergebnis der äußeren SELECT-Anweisung wird mit einem Wert in der Subquery verknüpft (korreliert).

Erläuterung

● SELECT hno, type, price FROM hotel.room room_table
Suche Hotelnummer, Zimmertyp, Preis aus der Tabelle room und benenne diese Tabelle in room_table um.

● WHERE price=
Behalte die Zeile, in der der Preis gleich dem Ergebnis der folgenden Subquery ist:

● (SELECT MAX(price) FROM hotel.room
(Beginn der Subquery) Suche den maximalen Preis aus der Tabelle room

● WHERE type = room_table.type)
wobei die Zimmertypen gleich den Zimmertypen der oben gefundenen Zeilen sein soll

Ergebnis

HNO | TYPE | PRICE
130 | double | 270
130 | single | 160
130 | suite | 700

SELECT cno, title, name FROM hotel.customer
WHERE EXISTS
(SELECT * FROM hotel.reservation
WHERE hotel.customer.cno = hotel.reservation.cno)

Anzeige nur der Kunden aus der Kundentabelle, für die eine oder mehrere Buchungen vorliegen

Ergebnis

CNO | TITLE | NAME
3000 | Mrs | Porter
3100 | Mr | Brown
3200 | Company | Datasoft
3600 | Mrs | Smith
3900 | Mr | Howe
4100 | Mrs | Baker
4300 | Company | TOOLware
4400 | Mr | Jenkins

Verwenden Sie EXISTS, wenn die Subquery nur herausfinden soll, ob eine Zeile existiert, die eine bestimmte Bedingung erfüllt.

Siehe auch:

SQL-Referenzhandbuch, EXISTS-Prädikat (exists_predicate)

Weitere Beispiele zur Datenanfrage