Grundlagen der Datenbanken
Aus einer Kundentabelle (KundenID, Name) und einer Bestelltabelle (BestellID, KundenID, Betrag) sollen die Namen der Kunden ermittelt werden, die noch nie bestellt haben. Welche SQL-Anweisung ist richtig?
- ASELECT Name FROM Kunde WHERE EXISTS (SELECT * FROM Bestellung WHERE Bestellung.KundenID = Kunde.KundenID)
- BSELECT Name FROM Kunde WHERE NOT EXISTS (SELECT * FROM Bestellung)
- CSELECT Name FROM Kunde WHERE NOT EXISTS (SELECT * FROM Bestellung WHERE Bestellung.KundenID = Kunde.KundenID)
Antwort und Erläuterung anzeigen
Antwort: C. SELECT Name FROM Kunde WHERE NOT EXISTS (SELECT * FROM Bestellung WHERE Bestellung.KundenID = Kunde.KundenID)
EXISTS ist ein Prädikat, das wahr ist, wenn die Unterabfrage in Klammern mindestens eine Zeile liefert, und falsch, wenn sie keine liefert; NOT EXISTS ist das Gegenteil. Wird in der Unterabfrage eine Spalte der äußeren Tabelle verwendet, wie bei Bestellung.KundenID = Kunde.KundenID, entsteht eine korrelierte Unterabfrage, die für jede Zeile der äußeren Kundentabelle prüft, ob dieser Kunde Bestellungen hat. In Kombination mit NOT EXISTS bleiben nur Kunden ohne jede Bestellung übrig. Mit EXISTS erhält man umgekehrt die Kunden, die schon bestellt haben. Fehlt eine Bedingung, die die Unterabfrage mit dem Kunden verknüpft, liefert die Unterabfrage immer Zeilen, sobald die Bestelltabelle mindestens eine Zeile hat; NOT EXISTS ist dann stets falsch, und das Ergebnis hat 0 Zeilen. Dasselbe Ergebnis erhält man auch mit einem LEFT OUTER JOIN, indem man die Zeilen auswählt, in denen die Spalten der Bestellseite NULL sind.