SQL Academy · Lektion

Anti-Joins und Semi-Joins (NOT EXISTS)

Finden Sie mit EXISTS/NOT EXISTS „Zeilen in A ohne Treffer in B“ (Anti-Join) und „Zeilen in A mit mindestens einem Treffer in B“ (Semi-Join).

Lektion 3 von 414 Schritte

Anti-Joins und Semi-Joins (NOT EXISTS) ist eine kostenlose SQL Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des SQL Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der SQL Academy-Kurs umfasst insgesamt 4 Lektionen.

Semi-Join: „Mindestens ein Treffer“

Geben Sie Zeilen aus A zurück, die mindestens eine passende Zeile in B haben – jedoch nur die Spalten von A. SQL implementiert Semi-Joins über EXISTS oder IN.

EXISTS-Semi-Join

Benutzer, die mindestens eine Bestellung aufgegeben haben:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

IN-Semi-Join

Dasselbe Ergebnis, ein anderer Stil:

SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders);

Warum EXISTS häufig gewinnt

EXISTS bricht früh ab: Die Suche endet pro äußerer Zeile beim ersten Treffer. IN materialisiert möglicherweise die gesamte innere Ergebnismenge. Moderne Planer optimieren oft zum gleichen Plan, aber EXISTS ist bei sehr großen inneren Mengen die sicherere Wahl.

Anti-Join: „Kein Treffer“

Benutzer, die NOCH NIE eine Bestellung aufgegeben haben – drei idiomatische Formen:

-- NOT EXISTS (preferred):
SELECT u.* FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

-- LEFT JOIN ... IS NULL:
SELECT u.* FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;

-- NOT IN (risky with NULLs):
SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM orders);

Warum NOT IN riskant ist

Wenn die innere Unterabfrage NULL enthält, liefert NOT IN NULL zurück – und WHERE verwirft Zeilen, deren Prädikat NULL ist. Ergebnis: null Zeilen. Dieses Problem tritt bei NOT EXISTS nicht auf.

Optimierung durch den Planer

Modernes PostgreSQL erkennt EXISTS und NOT EXISTS als Muster für Semi-/Anti-Joins und kann sie mit Hash-Joins ausführen:

EXPLAIN ANALYZE
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
-- → Hash Anti Join

Anti-Joins über mehrere Spalten

Verwenden Sie zusammengesetzte Schlüssel:

SELECT * FROM order_items oi
WHERE NOT EXISTS (
  SELECT 1 FROM shipments s
  WHERE s.order_id = oi.order_id
    AND s.line_no  = oi.line_no
);

Semi-Join mit EXISTS + zusätzlichem Prädikat

Fügen Sie der inneren Unterabfrage Filter hinzu:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.user_id = u.id
    AND o.status = 'paid'
    AND o.created_at >= NOW() - INTERVAL '30 days'
);

Die Korrelationsspalte indexieren

Sowohl bei EXISTS als auch bei NOT EXISTS filtert die innere Unterabfrage anhand des Schlüssels der äußeren Zeile. Ohne Index auf diesem Schlüssel erhalten Sie einen Scan pro äußerer Zeile:

CREATE INDEX orders_user_id_idx ON orders(user_id);

Wann LEFT JOIN ... IS NULL verwendet wird

Für Dashboards, die auch die Spalten der nicht übereinstimmenden Seite benötigen, ist der LEFT-JOIN-Stil eine natürliche Wahl. Für eine reine Anti-Join-Semantik ist NOT EXISTS klarer.

Über SQL hinaus: Bloom-Filter

Bei sehr großen Anti-Joins kann ein Bloom-Filter als Vorfilter helfen. PostgreSQL unterstützt bloom-Indizes über die bloom-Erweiterung.

Zusammenfassung

Semi-Join = „Treffer vorhanden“; Anti-Join = „kein Treffer“.

  • EXISTS für Semi-Joins
  • NOT EXISTS für Anti-Joins (NULL-sicher)
  • Die Korrelationsspalte indexieren
  • NOT IN vermeiden, sofern die innere Abfrage NULL enthalten kann

Kurztest

Sie möchten Benutzer finden, die NOCH NIE eine Bestellung aufgegeben haben. Welche SQL-Variante ist am sichersten und idiomatischsten?

Kostenlos starten

Lerne SQL mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
46
Lektionen
183

Häufig gestellte Fragen

Ist die Lektion „Anti-Joins und Semi-Joins (NOT EXISTS)“ kostenlos?

Ja — der vollständige Text von „Anti-Joins und Semi-Joins (NOT EXISTS)“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des SQL Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der SQL Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Anti-Joins und Semi-Joins (NOT EXISTS)“?

Finden Sie mit EXISTS/NOT EXISTS „Zeilen in A ohne Treffer in B“ (Anti-Join) und „Zeilen in A mit mindestens einem Treffer in B“ (Semi-Join). Du übst SQL Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um SQL Academy zu starten?

Keine Vorkenntnisse erforderlich. SQL Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Anti-Joins und Semi-Joins (NOT EXISTS)“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser SQL Academy-Lektion Code schreiben und ausführen?

Ja. Jede SQL Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Cross Joins und kartesische Produkte
  2. Laterale Joins (LATERAL JOIN)
  3. Anti-Joins und Semi-Joins (NOT EXISTS)
  4. Performance-Tuning für Joins über mehrere Tabellen
← Zurück zu SQL Academy