| Syntax :
| SELECT
| <Spalte1>
|
| |
FROM
| <Tabelle>
|
| |
WHERE
| <Spalte2> IN (SELECT <Spalte3>)
|
| |
|
FROM <Tabelle>
|
| |
|
[WHERE <Bedingung>])
|
| Hinweis :
| Spalte 1, Spalte 2 und Spalte 3 müssen nicht unterschiedlich sein.
|
| Beispiel :
| Gesucht werden die Nachnamen aller Mitarbeiter, die am Projekt '3' arbeiten.
|
| |
SELECT
| nach_name
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| pers_nr IN (SELECT pers_nr
|
| |
|
FROM Arbeitet_an
|
| |
|
WHERE pro_nr = 3)
|
| Hinweis :
| Jede Anfrage, die eine Unteranfrage mit dem IN-Operator enthält, ist als Equijoin formulierbar (gilt nicht für NOT IN). So ist die folgende Abfrage äquivalent zur letzten.
|
| Beispiel :
| SELECT
| M.nach_name
|
| |
FROM
| Mitarbeiter M, Arbeitet_an A
|
| |
WHERE
| M.mnr = A.mnr AND
|
| |
|
A.pnr = 3
|
| Hinweis :
| In einer Unterabfrage kann wieder eine Unterabfrage eingebettet werden.
|
| Beispiel :
| Gesucht werden die Personalnummern aller Mitarbeiter, die an einem Projekt arbeiten, dessen Standort Köln ist.
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| pers_nr IN (SELECT pers_nr
|
| |
|
FROM Arbeitet_an
|
| |
|
WHERE pnr IN (SELECT pnr
|
| |
|
FROM Projekt
|
| |
|
WHERE ort = 'Koeln' )
|
| Hinweis :
| Um das Ergebnis einer Unterbfrage zu negieren, kann der NOT-Operator benutzt werden.
|
| Beispiel :
| Gesucht werden die Nachnamen aller Mitarbeiter, die nicht am Projekt '3' arbeiten.
|
| |
SELECT
| nach_name
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| pers_nr NOT IN (SELECT pers_nr
|
| |
|
FROM Arbeitet_an
|
| |
|
WHERE pro_nr = 3)
|
| Beispiel :
| Gesucht werden die Personalnummern aller Mitarbeiter, die am Projekt mit Standort Köln arbeiten.
|
| |
SELECT
| pers_nr
|
| |
FROM
| Arbeitet_an
|
| |
WHERE
| pro_nr = (SELECT pro_nr
|
| |
|
FROM Projekt
|
| |
|
WHERE ort = 'Koeln')
|
| Hinweis :
| Ein einfacher Vergleich mit dem Ergebnis einer Unteranfrage ist nur dann erlaubt, wenn die Unteranfrage genau einen Wert liefert. Ist dies nicht der Fall (oder nicht sicher), so muß zusätzlich angegeben werden, ob der Vergleich bezüglich einem (ANY) oder allen (ALL) Werten der Unteranfrage gelten muß. Das letzte Beispiel führt also nur dann zu einem (korrekten) Ergebnis, wenn nur ein Projekt den Standort Köln aufweist.
|
| Beispiel :
| Gesucht wird die Personalnummer der Mitarbeiter, die mindestens soviel verdienen wie die Kollegen.
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| gehalt >= ALL (SELECT gehalt
|
| |
|
FROM Mitarbeiter)
|
| |
Die folgende Abfrage liefert das gleiche Ergebnis:
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| gehalt >= (SELECT MAX (gehalt))
|
| |
|
FROM Mitarbeiter)
|
| Beispiel :
| Gesucht wird die Personalnummer der Mitarbeiter, die nicht das kleinste Gehalt aufweisen.
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| gehalt > ANY (SELECT gehalt
|
| |
|
FROM Mitarbeiter)
|
| |
Die folgende Abfrage liefert das gleiche Ergebnis:
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter
|
| |
WHERE
| gehalt > (SELECT MIN (gehalt))
|
| |
|
FROM Mitarbeiter)
|
| Beispiel :
| Gesucht werden die Mitarbeiter, für die es kein Projekt gibt, an dem sie nicht mitarbeiten.
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter M
|
| |
WHERE
| NOT EXISTS (SELECT *
|
| |
|
FROM Projekt P
|
| |
|
WHERE NOT EXISTS (SELECT *
|
| |
|
FROM Arbeitet_an
|
| |
|
WHERE pro_nr = P.pro_nr AND
|
| |
|
pers_nr = M.pers_nr ))
|
| Hinweis :
| Eine andere Möglichkeit diese Anfrage zu formulieren, nutzt die Aggregatfunktion count(). Findet man einen Mitarbeiter, der an n verschiedenen Projekten mitarbeitet und insgesamt existieren nur n Projekte, dann muß er folglich an allen Projekten dieser Abteilung mitarbeiten.
|
| |
SELECT
| pers_nr
|
| |
FROM
| Mitarbeiter M
|
| |
WHERE
| pers_nr IN (SELECT pers_nr
|
| |
|
FROM Arbeitet_an A, Projekt P
|
| |
|
WHERE A.pro_nr = P.pro_nr
|
| |
|
GROUP BY pers_nr
|
| |
|
HAVING COUNT (DISTINCT pro_nr) = (SELECT COUNT (*)
|
| |
|
FROM Projekt))
|
| Beispiel :
| Finde die Abteilungsleiter, deren Untergebenen alle in ihrer Abteilung arbeiten. Erster Schritt ist wieder die Umformulierung der "für alle"-Bedingung: "Finde jeden Abteilungsleiter, der keinen Untergebenen hat, der nicht in seiner Abteilung arbeitet."
|
| |
SELECT
| leiter_nr
|
| |
FROM
| Abteilung A
|
| |
WHERE
| NOT EXISTS (SELECT *
|
| |
|
FROM Mitarbeiter M
|
| |
|
WHERE M.vorg_nr = A.leiter_nr AND
|
| |
|
A.anr <> M.anr)
|