CodeGym /Kurse /SQL SELF /Überprüfung der Dateneexistenz mit EXISTS u...

Überprüfung der Dateneexistenz mit EXISTS und NOT EXISTS

SQL SELF
Level 13 , Lektion 3
Verfügbar

Willkommen zur neuen SQL-Vorlesung! Heute schauen wir uns die unscheinbarsten, aber mega mächtigen Operatoren an – EXISTS und NOT EXISTS. Stell dir einen Spion vor, der keine Spuren hinterlässt, aber sofort meldet: "Ja, das Objekt existiert" oder "Nee, hier ist nix". Diese Operatoren liefern keine Daten direkt zurück, aber sie ermöglichen logisch präzise Checks in deinen Queries.

Fangen wir mit den Basics an. EXISTS ist ein Operator, der prüft, ob Datensätze existieren als Ergebnis einer Subquery. Wenn die Subquery mindestens einen Datensatz liefert, gibt EXISTS TRUE zurück, sonst FALSE.

SELECT 1
WHERE EXISTS (
    SELECT * 
    FROM students 
    WHERE grade > 3.5
);

Wie du siehst, interessieren uns die eigentlichen Daten der Subquery nicht, sondern nur, ob solche Zeilen existieren. Wenn mindestens ein Datensatz das Kriterium erfüllt, gibt die Query 1 zurück.

Syntax von EXISTS

Die Syntax von EXISTS ist simpel:

SELECT spalten
FROM tabelle
WHERE EXISTS (
    SELECT 1
    FROM andere_tabelle
    WHERE bedingung
);

Erklärung:

  • Die verschachtelte Subquery in EXISTS kann jede beliebige Query sein.
  • Das Ergebnis der Subquery entscheidet, ob TRUE oder FALSE zurückkommt.

Beispiel: Gibt es Studenten mit einer Note über 4?

Stell dir die Tabelle students vor:

id name grade
1 Otto 3.2
2 Anna 4.7
3 Dan 5.0
4 Lina 2.9

Angenommen, wir wollen checken, ob es Studenten mit einer Note über 4 gibt. Wir nutzen folgende Query:

SELECT 'Es gibt Studenten mit hoher Punktzahl!'
WHERE EXISTS (
    SELECT 1
    FROM students
    WHERE grade > 4
);

Ergebnis:

Es gibt Studenten mit hoher Punktzahl!

Warum ist EXISTS schneller als IN?

Der Hauptvorteil von EXISTS ist, dass er die Subquery sofort abbricht, sobald das erste Match gefunden wurde. Das heißt, wenn du nur checken willst, ob Daten existieren, kann EXISTS extrem effizient sein.

Stell dir vor, die Tabelle students hat Millionen von Zeilen, aber wir suchen nur ein einziges existierendes Match (grade > 4). Sobald SQL die erste passende Zeile findet, ist die Query fertig.

Verwendung von NOT EXISTS

Jetzt reden wir über NOT EXISTS. Dieser Operator ist das Gegenteil von EXISTS. Er gibt TRUE zurück, wenn die Subquery keinen einzigen Datensatz liefert.

Beispiel: Studenten ohne Noten (NULL) finden

Angenommen, in unserer Tabelle gibt es Studenten, die noch keine Noten haben:

id name grade
1 Otto NULL
2 Anna 4.7
3 Dan 5.0
4 Lina NULL

Wir wollen alle Studenten mit fehlenden Noten auswählen. Wir nutzen NOT EXISTS:

SELECT *
FROM students s
WHERE NOT EXISTS (
    SELECT 1
    FROM students 
    WHERE grade IS NOT NULL
    AND id = s.id
);

Ergebnis:

id name grade
1 Otto NULL
4 Lina NULL

Vergleich von EXISTS und IN

Manchmal sieht es so aus, als würden EXISTS und IN das Gleiche machen. Auf den ersten Blick stimmt das, aber es gibt Unterschiede. Besonders wenn irgendwo ein NULL auftaucht. Dann kann sich IN komisch verhalten, während EXISTS dich rettet.

Schauen wir uns das mal an einem Beispiel an.

Tabelle courses (Kurse, die man belegen kann):

course_id name
1 Mathematik
2 Geschichte

Und hier die Studenten:

student_id name
1 Alex Lin
2 Anna Song
3 Maria Chi
4 Dan Seth
5 Shadow Moon

Tabelle enrollments (wer ist in welchem Kurs eingeschrieben):

student_id course_id
1 1
2 2
3 NULL

Wir wollen die Namen der Kurse auswählen, für die sich jemand eingeschrieben hat. Klingt einfach.

Mit IN:

SELECT name
FROM courses
WHERE course_id IN (
    SELECT course_id 
    FROM enrollments
);

Auf den ersten Blick sollte das klappen. Aber wenn in enrollments ein NULL bei courseid steht, wie bei Maria Chi, kann IN ... gar nichts zurückgeben! Denn NULL macht die Subquery "undefiniert" und SQL ist verwirrt: Vielleicht ist NULL genau die courseid, die wir suchen?

Mit EXISTS:

SELECT name
FROM courses c
WHERE EXISTS (
SELECT 1
FROM enrollments e
WHERE c.course_id = e.course_id
);

Aber EXISTS prüft: "Gibt es mindestens eine Zeile, wo course_id übereinstimmt?" – und das war's. Es stört sich nicht an NULL, denn es sucht konkrete Matches, nicht eine Werteliste.

Fazit: Wenn in der Subquery ein NULL vorkommen kann, nutze besser EXISTS, damit du keine Überraschungen erlebst.

Echte Aufgabenbeispiele

Tabelle students:

id name
1 Alex Lin
2 Anna Song
3 Maria Chi
4 Dan Seth
5 Shadow Moon

Tabelle enrollments:

student_id course_id
1 1
2 2
3 NULL

Beispiel 1. Studenten, die in Kursen eingeschrieben sind

Wir finden alle, die irgendwo schon aufgetaucht sind – also in einen Kurs eingeschrieben sind (auch wenn's komisch ist, wie bei Maria Chi):

SELECT name
FROM students s
WHERE EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE s.id = e.student_id
);

Ergebnis:

Alex Lin
Anna Song
Maria Chi

Wenn ein Student irgendwie in enrollments auftaucht – kommt er in die Auswahl, auch wenn sein course_id unklar ist.

Beispiel 2. Studenten ohne Kurse

Jetzt suchen wir die, die einfach nur im System existieren – aber noch nirgends eingeschrieben sind:

SELECT name
FROM students s
WHERE NOT EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE s.id = e.student_id
);

Ergebnis:

Dan Seth
Shadow Moon

Scheint so, als hätten diese beiden noch keinen passenden Kurs gefunden. Oder sie haben einfach vergessen, sich einzuschreiben :)

Beispiel 3. Auswahl von Kursen mit mehr als 5 eingeschriebenen Studenten

Tabelle courses:

course_id name
1 Mathematik
2 Geschichte
3 Biologie
4 Philosophie

Tabelle enrollments:

student_id course_id
1 1
2 1
3 1
4 1
5 1
6 1
7 2
8 2
9 2
10 NULL

Wir wollen die Kurse finden, in die sich mehr als fünf Studenten eingeschrieben haben. Hier fragt EXISTS quasi: "Gibt es für diesen Kurs mindestens eine Gruppe von Einträgen, wo mehr als fünf Studenten drin sind?"

SELECT name
FROM courses c
WHERE EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE c.course_id = e.course_id
    GROUP BY e.course_id
    HAVING COUNT(*) > 5
);

Ergebnis:

Mathematik

Nur für den Kurs "Mathematik" (course_id = 1) sind sechs Studenten eingeschrieben. Die anderen Kurse sind noch nicht so beliebt.

Häufige Fehler bei EXISTS und NOT EXISTS

  1. Falsches Verständnis der Subquery-Syntax. Prüfe immer, dass die Subquery korrekt auf die äußere Tabelle verweist.
  2. Vergessene NULL-Prüfung. Auch wenn du EXISTS nutzt, musst du manchmal explizit NULL behandeln.
  3. Kein Index auf den Feldern der Subquery. Das kann die Ausführung der Query stark verlangsamen.

Das war's für heute! Jetzt weißt du, wie du EXISTS und NOT EXISTS nutzt, um die Existenz von Daten zu prüfen, und kennst die Unterschiede zu IN. In der nächsten Vorlesung tauchen wir tiefer in Subqueries ein und schauen uns deren Einsatz in SELECT für aggregierte Daten an.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION