Gecorreleerde EXISTS en NOT EXISTS
Het robuuste alternatief voor een anti-join dat correct met NULL's omgaat
Gecorreleerde EXISTS en NOT EXISTS is een gratis Voorbereiding op programmeerinterviews-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 Voorbereiding op programmeerinterviews. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Voorbereiding op programmeerinterviews bevat in totaal 4 lessen.
EXISTS test op aanwezigheid
EXISTS neemt een subquery en retourneert TRUE zodra die subquery minstens één rij oplevert, en anders FALSE. De rijen zelf worden nooit geretourneerd.
Met een gecorreleerde subquery erin wordt EXISTS een aanwezigheidstest per buitenste rij: "bestaat er een overeenkomende rij voor deze buitenste rij?"
Omdat EXISTS stopt bij de eerste overeenkomst, maakt het niet uit hoeveel rijen overeenkomen. Dat detail over de werking is een geliefd interviewpunt.
Een eenvoudige gecorreleerde EXISTS
Vind klanten die minstens één bestelling hebben geplaatst. De binnenste query is gecorreleerd via o.customer_id = c.customer_id.
Voor elke klant vraagt EXISTS: is er een bestelling voor deze klant? Zo ja, behoud je de klant.
SELECT c.customer_id, c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);Waarom SELECT 1 in EXISTS staat
Je ziet SELECT 1, SELECT * of SELECT NULL binnen EXISTS. Ze zijn allemaal gelijkwaardig.
EXISTS controleert alleen of er rijen worden geretourneerd, nooit wat ze bevatten. De kolommen in de uitvoer zijn dus niet relevant. De optimalisator negeert ze.
SELECT 1 is een veelgebruikte conventie die de bedoeling duidelijk maakt: "ik geef alleen om aanwezigheid". Kies één vorm en blijf consistent; laat een interviewer niet denken dat de kolommenlijst hier van belang is.
NOT EXISTS vindt wat ontbreekt
NOT EXISTS keert de test om: behoud de buitenste rij alleen wanneer de gecorreleerde subquery geen rijen retourneert.
Dit is de klassieke anti-join: klanten zonder bestellingen, producten die nooit zijn verkocht en studenten zonder inzendingen.
SELECT c.customer_id, c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);De NULL-valkuil van NOT IN
Dit is een geliefd interviewonderwerp. NOT IN tegen een subquery die NULL kan bevatten, gedraagt zich verraderlijk: als de lijst ook maar één NULL bevat, retourneert NOT IN helemaal geen rijen.
Dat komt doordat een vergelijking met NULL UNKNOWN oplevert en NOT IN vereist dat elke vergelijking onwaar is. Eén UNKNOWN maakt de hele voorwaarde ongeldig.
NOT EXISTS heeft hier geen last van: het controleert gewoon of er rijen aanwezig zijn en gaat veilig met NULL om.
-- Risky: returns nothing if any o.customer_id is NULL
SELECT c.customer_id FROM customers c
WHERE c.customer_id NOT IN (SELECT o.customer_id FROM orders o);
-- Safe: NULLs do not break it
SELECT c.customer_id FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id
);Waarom NOT EXISTS NULL-veilig is
De reden zit in de logica voor het vinden van overeenkomsten. NOT EXISTS controleert of een binnenste rij voldoet aan o.customer_id = c.customer_id.
Een rij waarin o.customer_id NULL is, voldoet nooit aan die gelijkheid (NULL = wat dan ook is UNKNOWN, niet TRUE) en telt dus gewoon niet als overeenkomst. De aanwezigheidstest blijft correct.
Bij NOT IN wordt diezelfde NULL onderdeel van een lijstvergelijking waarvan het resultaat UNKNOWN alle uitvoer wegneemt. Daarom geven beoordelaars in sollicitatiegesprekken voor seniorfuncties de voorkeur aan NOT EXISTS.
EXISTS met extra voorwaarden
De gecorreleerde subquery kan meer predicaten bevatten. Zoek klanten die ten minste één bestelling van meer dan 1000 hebben geplaatst.
De extra voorwaarde staat binnen de EXISTS-subquery en geldt afzonderlijk per klant.
SELECT c.customer_id, c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
AND o.amount > 1000
);Prestaties: gedrag bij kortsluiten
EXISTS kan het doorzoeken van de binnenste relatie stoppen zodra er één overeenkomende rij is gevonden. Er wordt geen volledige resultatenset opgebouwd of geteld.
Daardoor is EXISTS doorgaans efficiënt, vooral wanneer de gecorreleerde kolom geïndexeerd is, omdat elke controle per rij snel een overeenkomst kan vinden en vervolgens kan stoppen.
Vergelijk dit met een gecorreleerde COUNT(*) > 0, die het tellen van elke overeenkomst afdwingt. Gebruik EXISTS bij voorkeur wanneer je alleen een ja-of-nee-antwoord nodig hebt.
EXISTS versus COUNT voor aanwezigheid
Sommige kandidaten schrijven een gecorreleerde telling om te controleren of iets aanwezig is. Dat werkt, maar kost onnodig moeite.
De COUNT-versie telt elke overeenkomende bestelling; EXISTS stopt na de eerste. Voor een eenvoudige controle op bestaan maakt EXISTS de bedoeling duidelijk en kan de optimalisator voortijdig stoppen.
-- Works but counts everything
SELECT c.customer_id FROM customers c
WHERE (SELECT COUNT(*) FROM orders o
WHERE o.customer_id = c.customer_id) > 0;
-- Better: stops at first match
SELECT c.customer_id FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id);Uitgewerkt voorbeeld: nooit bestelde producten
Een klassieke vraag over een antijoin in sollicitatiegesprekken: geef producten weer die nooit zijn besteld. NOT EXISTS komt bijna overeen met de formulering van de vereiste.
Controleer voor elk product of een bestelregel ernaar verwijst; houd alleen de producten over waarvoor dat niet het geval is.
SELECT p.product_id, p.name
FROM products p
WHERE NOT EXISTS (
SELECT 1
FROM order_items oi
WHERE oi.product_id = p.product_id
);EXISTS in NOT EXISTS voor delingsachtige query's
EXISTS nesten binnen NOT EXISTS drukt relationele deling uit: "zoek rijen die overeenkomen met ALLE elementen uit een verzameling." Een klassieke vraag is: "klanten die elk product in een categorie hebben besteld".
De logica is als volgt: houd een klant over wanneer er geen product is dat die klant niet heeft besteld. Die dubbele ontkenning is kenmerkend voor een delingsquery, en interviewers gebruiken dit om grondige kennis van EXISTS te testen.
SELECT c.customer_id
FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM products p
WHERE p.category = 'Coffee'
AND NOT EXISTS (
SELECT 1 FROM order_items oi
JOIN orders o ON o.order_id = oi.order_id
WHERE oi.product_id = p.product_id
AND o.customer_id = c.customer_id
)
);Korte controle
Kies de veiligste manier om klanten zonder bestellingen te vinden.
Samenvatting: gecorreleerde EXISTS en NOT EXISTS
Belangrijkste punten:
EXISTScontroleert per rij of iets aanwezig is en stopt bij de eerste overeenkomst; welke kolom je erin kiest, is niet van belang (gebruikSELECT 1).NOT EXISTSis de NULL-veilige antijoin voor het vinden van rijen zonder overeenkomst.NOT INmet een NULL in de lijst retourneert niets; gebruik bij voorkeurNOT EXISTS.- Voor het controleren van bestaan is EXISTS beter dan een gecorreleerde
COUNT(*) > 0, omdat het vroegtijdig stopt.
Noem de NULL-valkuil van NOT IN uit jezelf; dat is een betrouwbaar teken van volwassen SQL-kennis.
Leer Voorbereiding op programmeerinterviews 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
- 90
- Lessen
- 360
Veelgestelde vragen
Is de les “Gecorreleerde EXISTS en NOT EXISTS” gratis?
Ja — de volledige tekst van “Gecorreleerde EXISTS en 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 Voorbereiding op programmeerinterviews wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Voorbereiding op programmeerinterviews bevat in totaal 4 lessen.
Wat leer ik in “Gecorreleerde EXISTS en NOT EXISTS”?
Het robuuste alternatief voor een anti-join dat correct met NULL's omgaat Je oefent met Voorbereiding op programmeerinterviews 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 Voorbereiding op programmeerinterviews te beginnen?
Ervaring vooraf is niet nodig. Voorbereiding op programmeerinterviews 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 “Gecorreleerde EXISTS en 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 Voorbereiding op programmeerinterviews?
Ja. Elke les over Voorbereiding op programmeerinterviews 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
- Anatomie van een gecorreleerde subquery
- Aggregaties per groep zonder GROUP BY
- Gecorreleerde EXISTS en NOT EXISTS
- Gecorreleerde subquery's herschrijven als joins