Rijen zonder overeenkomst vinden (anti-join)
Het patroon LEFT JOIN / IS NULL om verweesde en ontbrekende gegevens te vinden
Rijen zonder overeenkomst vinden (anti-join) 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.
De anti-joinvraag
Een van de meest gestelde vragen over outer joins is: "Zoek klanten die nooit een bestelling hebben geplaatst." Of: "Geef producten weer die nooit zijn verkocht," of "bestellingen zonder overeenkomende klant."
Al deze vragen hebben dezelfde vorm: rijen in één tabel waarvoor in een andere tabel geen overeenkomst bestaat. Het duidelijke patroon is de anti-join, opgebouwd uit een LEFT JOIN en een filter met IS NULL.
Het kernidee
Begin met een LEFT JOIN: die behoudt elke linkerrij, en rijen zonder overeenkomst krijgen NULL in de kolommen van de rechtertabel.
De rijen zonder overeenkomst zijn dus precies de rijen waarbij een kolom van de rechtertabel NULL is. Filter daarop en je isoleert de rijen zonder overeenkomst. Dat is de hele truc.
Het patroon opbouwen
Hier is de standaardanti-join waarmee je klanten zonder bestellingen vindt. Lees hem in twee stappen: LEFT JOIN behoudt alle klanten en daarna houdt WHERE o.customer_id IS NULL alleen de rijen zonder overeenkomst over.
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id
WHERE o.customer_id IS NULL;
-- only customers with zero ordersWaarom dit stap voor stap werkt
Loop dit na met onze gegevens, waarin Carol geen bestellingen heeft:
- LEFT JOIN levert Alice (x2), Bob (x1) en Carol met NULL-waarden in de rechterkolommen.
WHERE o.customer_id IS NULLverwijdert Alice en Bob (hun rechterkolommen bevatten echte waarden).- Alleen de rij van Carol, die met NULL-waarden is aangevuld, blijft over.
Het filter wordt na de join uitgevoerd, dus het ziet die NULL-waarden en selecteert precies de verweesde rijen.
De juiste kolom testen
Test een kolom van de rechtertabel die bij een echte overeenkomst nooit geldig NULL kan zijn, bij voorkeur de joinsleutel of primaire sleutel.
Als je een kolom van de rechtertabel test die NULL mag zijn, zoals o.shipped_at, vang je ook bestaande maar nog niet verzonden bestellingen op. Dat is een fout antwoord. Door o.customer_id (de joinsleutel) of o.id (de primaire sleutel) te testen, weet je zeker dat NULL betekent: "er is geen rij gevonden die overeenkomt."
-- SAFE: join key / primary key
WHERE o.id IS NULL
-- RISKY: a nullable data column
WHERE o.shipped_at IS NULL -- catches unshipped too!Anti-join versus NOT IN
Interviewers vergelijken de anti-join met NOT IN. Ze lijken gelijkwaardig, maar gedragen zich anders bij NULL-waarden.
Als de subquery ook maar één NULL oplevert, geeft NOT IN helemaal geen rijen terug: een beruchte stille fout. De anti-join met LEFT JOIN / IS NULL is hiervoor ongevoelig.
-- DANGEROUS if any customer_id is NULL
SELECT id, name FROM customers
WHERE id NOT IN (SELECT customer_id FROM orders);
-- SAFE anti-join, same intent
SELECT c.id, c.name FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;Anti-join versus NOT EXISTS
De andere gelijkwaardige vorm is NOT EXISTS met een gecorreleerde subquery. Ook die verwerkt NULL-waarden correct en is vaak net zo snel.
Alle drie de vormen (LEFT JOIN/IS NULL, NOT EXISTS en NOT IN) kunnen anti-joins uitdrukken, maar kies in een interview bij voorkeur LEFT JOIN/IS NULL of NOT EXISTS vanwege hun veilige omgang met NULL-waarden. Als je de valkuil van NOT IN noemt, levert dat punten op.
SELECT c.id, c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);Een veelgemaakte fout
Een veelgemaakte fout is de voorwaarde voor rijen zonder overeenkomst in de ON-clausule te zetten in plaats van in WHERE.
Met ... ON o.customer_id = c.id AND o.id IS NULL filter je het resultaat niet. Je verandert alleen wat als overeenkomst telt, en elke klant blijft door de LEFT JOIN behouden. De test met IS NULL moet in WHERE staan en na de join worden toegepast. In de volgende les behandelen we deze valkuil volledig.
Verweesde kindrijen vinden
Het patroon werkt ook andersom. Om bestellingen te vinden die naar een ontbrekende klant verwijzen (weesrijen, een controle op gegevensintegriteit), behoud je orders en test je de klantkant op NULL.
SELECT o.id AS order_id, o.customer_id
FROM orders o
LEFT JOIN customers c
ON c.id = o.customer_id
WHERE c.id IS NULL;
-- orders pointing to a non-existent customerDe weesrijen tellen
Vaak wordt alleen om een aantal gevraagd: "Hoeveel klanten hebben nooit besteld?" Wikkel de anti-join in een query of tel rechtstreeks.
Omdat de anti-join al één rij per weesrij teruggeeft, is een gewone COUNT(*) hier correct: er is precies één rij per klant zonder overeenkomst.
SELECT COUNT(*) AS never_ordered
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;Het herbruikbare sjabloon
Onthoud dit skelet van drie regels; het lost een enorme groep interviewvragen op:
FROM keep_table kLEFT JOIN other o ON o.fk = k.idWHERE o.id IS NULL
Vervang de tabellen en sleutels om onverkochte producten, niet-toegewezen tickets, gebruikers zonder aanmeldingen en alles te vinden dat wordt omschreven als "X zonder overeenkomende Y."
Korte controle
Je hebt producten nodig die nooit in order_items zijn voorgekomen.
Samenvatting
De anti-join vindt rijen zonder overeenkomst: LEFT JOIN en daarna WHERE right_key IS NULL.
- Test de joinsleutel of primaire sleutel, nooit een gegevenskolom die NULL mag zijn.
- De test met
IS NULLhoort inWHERE, niet inON. - Dit is gelijkwaardig aan
NOT EXISTS; geef daar de voorkeur aan bovenNOT IN, dat bij NULL-waarden niet goed werkt. - Draai de tabellen om om verweesde kindrijen te vinden.
Eén sjabloon, veel vragen: "X zonder overeenkomende Y."
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 “Rijen zonder overeenkomst vinden (anti-join)” gratis?
Ja — de volledige tekst van “Rijen zonder overeenkomst vinden (anti-join)” 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 “Rijen zonder overeenkomst vinden (anti-join)”?
Het patroon LEFT JOIN / IS NULL om verweesde en ontbrekende gegevens te vinden 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 “Rijen zonder overeenkomst vinden (anti-join)”?
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
- LEFT JOIN en niet-overeenkomende rijen behouden
- Semantiek van RIGHT en FULL OUTER JOIN
- Rijen zonder overeenkomst vinden (anti-join)
- De valkuil van WHERE bij outer joins