SQL Academy · Les

Anti-joins en semi-joins (NOT EXISTS)

Vind ‘rijen in A zonder overeenkomst in B’ (anti-join) en ‘rijen in A met minstens één overeenkomst in B’ (semi-join) met EXISTS/NOT EXISTS.

Les 3 van 414 stappen

Anti-joins en semi-joins (NOT EXISTS) is een gratis SQL Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject SQL Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus SQL Academy bevat in totaal 4 lessen.

Semijoin: "heeft ten minste één overeenkomst"

Retourneer rijen uit A die minstens één overeenkomende rij in B hebben, maar alleen de kolommen van A. SQL implementeert semijoins via EXISTS of IN.

EXISTS-semijoin

Gebruikers die minstens één order hebben geplaatst:

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

IN-semijoin

Hetzelfde resultaat, een andere stijl:

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

Waarom EXISTS vaak wint

EXISTS stopt zodra de eerste overeenkomst voor de buitenste rij is gevonden. IN kan de volledige binnenste verzameling materialiseren. Moderne queryplanners optimaliseren beide vaak naar hetzelfde plan, maar EXISTS is de veiligere keuze bij zeer grote binnenste verzamelingen.

Antijoin: "heeft geen overeenkomst"

Gebruikers die NOOIT een order hebben geplaatst — drie idiomatische vormen:

-- 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);

Waarom NOT IN riskant is

Als de binnenste subquery NULL bevat, retourneert NOT IN NULL — en WHERE verwijdert rijen waarvan het predicaat NULL is. Resultaat: nul rijen. NOT EXISTS heeft dit probleem niet.

Optimalisatie door de queryplanner

Modern PostgreSQL herkent EXISTS en NOT EXISTS als patronen voor semi- en antijoins en kan ze uitvoeren met hash joins:

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

Antijoins met meerdere kolommen

Gebruik samengestelde sleutels:

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
);

Semijoin met EXISTS + extra predicaat

Voeg filters toe aan de binnenste subquery:

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'
);

Indexeer de correlatiekolom

Zowel bij EXISTS als bij NOT EXISTS filtert de binnenste subquery op de sleutel van de buitenste rij. Zonder index op die sleutel krijg je één scan per buitenste rij:

CREATE INDEX orders_user_id_idx ON orders(user_id);

Wanneer je LEFT JOIN ... IS NULL gebruikt

Voor dashboards die ook de kolommen van de niet-overeenkomende kant nodig hebben, past de LEFT JOIN-stijl natuurlijk. Voor pure antijoin-semantiek is NOT EXISTS duidelijker.

Buiten SQL: Bloomfilters

Bij zeer grote antijoins kan een voorafgaand filter met een Bloomfilter helpen. PostgreSQL ondersteunt bloom-indexen via de bloom-extensie.

Samenvatting

Semijoin = "heeft overeenkomst"; antijoin = "heeft geen overeenkomst".

  • EXISTS voor semijoins
  • NOT EXISTS voor antijoins (veilig voor NULL)
  • Indexeer de correlatiekolom
  • Vermijd NOT IN tenzij de binnenste verzameling geen NULL kan bevatten

Korte controle

Je wilt gebruikers die NOOIT een order hebben geplaatst. Wat is de veiligste en meest idiomatische SQL?

Gratis beginnen

Leer SQL met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
46
Lessen
183

Veelgestelde vragen

Is de les “Anti-joins en semi-joins (NOT EXISTS)” gratis?

Ja — de volledige tekst van “Anti-joins en semi-joins (NOT EXISTS)” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus SQL Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus SQL Academy bevat in totaal 4 lessen.

Wat leer ik in “Anti-joins en semi-joins (NOT EXISTS)”?

Vind ‘rijen in A zonder overeenkomst in B’ (anti-join) en ‘rijen in A met minstens één overeenkomst in B’ (semi-join) met EXISTS/NOT EXISTS. Je oefent met SQL Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met SQL Academy te beginnen?

Ervaring vooraf is niet nodig. SQL Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Anti-joins en semi-joins (NOT EXISTS)”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over SQL Academy?

Ja. Elke les over SQL Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Cross joins en Cartesische producten
  2. Lateral joins (LATERAL JOIN)
  3. Anti-joins en semi-joins (NOT EXISTS)
  4. Prestaties van joins met meerdere tabellen optimaliseren
← Terug naar SQL Academy