Unterabfragen (Subselect, Subqueries) sind Abfragen
(SELECT-Anweisungen), die in andere Abfragen eingebettet sind. Sie
werden in der WHERE-Klausel der
SELECT-Anweisung angegeben.
1. Unterabfragen mit einem Ergebniswert
Wenn eine
SELECT-Anweisung ein Ergebnis liefert: z.B. die Autoren-Id des Autors "White" aus der "Verleger"-Datenbank:
SELECT A_id FROM Autoren WHERE A_nname = 'White'
|
| A_id |
| -------- |
| 172-32-1176 |
|
So kann mit diesem Ergebnis die entsprechende Titel-Id ermittelt werden.
SELECT Titel_id FROM Titelautor WHERE A_id = '172-32-1176'
|
|
Schneller kommen wir zu dieser Lösung, wenn wir das Ergebnis der ersten
Abfrage (172-32-1176) direkt in die WHERE-Klausel der zweiten Abfrage
einsetzen:
SELECT Titel_id FROM Titelautor
WHERE A_id = (SELECT A_id FROM Autoren WHERE A_nname = 'White')
In diesem Beispiel darf die innere Abfrage NUR EINEN WERT liefern,
denn nur dann ist der Ausdruck A_id = wert gültig (A_id = wert, wert,
wert ... ist keine gültige Bedingung):
SELECT Titel_id FROM Titelautor
WHERE A_id = (SELECT A_id FROM Autoren WHERE A_nname = 'Ringer')
liefert eine Fehlermeldung, weil mehr als ein Autor namens "Ringer" existiert.
2. Unterabfragen mit mehreren Ergebniswerten
Für den Fall, dass eine innere Abfrage mehrere Ergebnisse liefert, können Sie die Operatoren IN, ALL, ANY und EXISTS einsetzen.
IN prüft, ob ein bestimmter Wert in einer Menge von Werten der Unterabfrage enthalten ist
Folgende
SELECT-Anweisung soll die Titel-Id aller Autoren aus Oakland liefern:
SELECT Titel_id FROM Titelautor
WHERE A_id IN (SELECT A_id FROM Autoren WHERE Ort = 'Oakland')
ALL prüft, ob eine Bedingung für alle Ergebnisse der Unterabfrage erfüllt ist.
Im folgenden Beispiel sei dies die Unterabfrage:
SELECT Titel_id, Tantiemen FROM Tantiemen_tab
WHERE Tantiemen > 15 AND Titel_id = 'PC1035'
|
| Titel_id | Tantiemen |
| -------- | ----------- |
| PC1035 | 16 |
| PC1035 | 18 |
|
Das sei die Hauptabfrage, die später durch die Unterabfrage eingeschränkt werden soll:
SELECT Titel_id, Tantiemen FROM Titel
|
| Titel_id | Tantiemen |
| -------- | ----------- |
| BU1032 | 10 |
| BU1111 | 10 |
| BU2075 | 24 |
| BU7832 | 10 |
| MC2222 | 12 |
| MC3021 | 24 |
| MC3026 | NULL |
| PC1035 | 16 |
| PC8888 | 10 |
| PC9999 | NULL |
| PS1372 | 10 |
| PS2091 | 12 |
| PS2106 | 10 |
| PS3333 | 10 |
| PS7777 | 10 |
| TC3218 | 10 |
| TC4203 | 14 |
| TC7777 | 10 | |
SELECT Titel_id, Tantiemen FROM Titel
WHERE Tantiemen >= ALL (SELECT Tantiemen FROM Tantiemen_tab
WHERE Tantiemen > 15 AND Titel_id = 'PC1035')
Die Hauptabfrage liefert hier Datensätze, deren Attribut "Tantiemen" alle größergleich sind, als diejenigen der Unterabfrage.
|
| Titel_id | Tantiemen |
| -------- | ----------- |
| BU2075 | 24 |
| MC3021 | 24 | |
ANY oder SOME prüft, ob eine Bedingung für mindestens ein Ergebnis der Unterabfrage erfüllt ist.
SELECT Titel_id, Tantiemen FROM Titel
WHERE Tantiemen >= ANY (SELECT Tantiemen FROM Tantiemen_tab
WHERE Tantiemen > 15 AND Titel_id = 'PC1035')
Die Hauptabfrage liefert hier Datensätze, bei denen das Attribut "Tantiemen" größergleich ist, als irgendein Attribut "Tantiemen" der Unterabfrage.
|
| | Titel_id | Tantiemen |
| -------- | ----------- |
| BU2075 | 24 |
| MC3021 | 24 |
| PC1035 | 16 |
|
(=ANY bzw. =SOME lässt sich durch IN ersetzen.)
EXISTS ist gleich TRUE, wenn die Unterabfrage mindestens eine Zeile
zurückliefert. (Das macht nur Sinn, wenn man die Werte in jedem Satz
der Unterabfrage mit Werten der Hauptabfrage zueinander in Beziehung
setzt.)
SELECT A_id FROM Titelautor
WHERE EXISTS (SELECT Titel_id FROM Titel
WHERE Tantiemen > 20 AND Titelautor.Titel_id = Titel.Titel_id)
(EXISTS lässt sich durch IN ersetzen.)
|
| | A_id |
| -------- |
| 213-46-8915 |
| 722-51-5454 |
| 899-46-2035 |
|
In der WHERE-Klausel gilt folgende Syntax für die Unterabfrage:
| ... WHERE | wobei |
Ausdruck [NOT] IN
Spalte {= | < > | < | > | <= | =>} [ANY | SOME | ALL]
[NOT] EXISTS | der Ausdruck in der Unterabfrage (nicht) vorkommt
der Wert der Spalte verglichen mit dem Ergebnis der Unterabfrage
die Unterabfrage (nicht) existieren muss |
| (SELECT-Anweisung) | Unterabfrage |