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'
Titel_id
--------
PS3333


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_idTantiemen
-------------------
PC103516
PC103518



Das sei die Hauptabfrage, die später durch die Unterabfrage eingeschränkt werden soll:

SELECT Titel_id, Tantiemen FROM Titel
Titel_idTantiemen
-------------------
BU103210
BU111110
BU207524
BU783210
MC222212
MC302124
MC3026NULL
PC103516
PC888810
PC9999NULL
PS137210
PS209112
PS210610
PS333310
PS777710
TC321810
TC420314
TC777710


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_idTantiemen
-------------------
BU207524
MC302124


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_idTantiemen
-------------------
BU207524
MC302124
PC103516
(=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:

... WHEREwobei
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

Last modified: Wednesday, 5 September 2018, 10:32 AM