SQL leren: EXISTS
Bestaat het? EXISTS en de valkuil van NOT IN
"Welke leden brachten nog nooit iemand anders aan?" Sanne wil ze een folder sturen. Je schrijft een nette query met `NOT IN`, en krijgt... niets. Daar zit een van de gemeenste valkuilen van SQL achter.
NOT IN, het omgekeerde
NOT IN met een subquery houdt de rijen die niet in de lijst staan. Deze query vindt de boeken die nog nooit werden uitgeleend.
Dat werkt prima, zolang er in de lijst geen NULL staat.
SELECT titel FROM boeken WHERE id NOT IN (SELECT boek_id FROM uitleningen)| titel |
|---|
| De vergeten toren |
| Fietsen door Europa |
| Brieven aan niemand |
De valkuil, NOT IN met NULL
aanbrenger_id is het lid dat iemand aanbracht, en is vaak NULL. Zoek je met NOT IN wie nooit iemand aanbracht, dan krijg je geen enkele rij. Hieronder tellen we ze: 0, al zijn het er in werkelijkheid zeven.
Waarom? 5 NOT IN (1, 2, NULL) betekent 5 <> 1 AND 5 <> 2 AND 5 <> NULL, en een vergelijking met NULL is nooit waar. Haal de NULL's dus uit de lijst, of gebruik NOT EXISTS.
SELECT COUNT(*) AS gevonden FROM leden WHERE id NOT IN (SELECT aanbrenger_id FROM leden)| gevonden |
|---|
| 0 |
SELECT id, naam, aanbrenger_id FROM leden| id | naam | aanbrenger_id |
|---|---|---|
| 1 | Sanne Willems | NULL |
| 2 | Jef Wouters | 1 |
| 3 | Amira El Idrissi | 1 |
| 4 | Pieter Desmet | NULL |
| 5 | Lotte Vandamme | 4 |
| 6 | Bert Claeys | NULL |
| 7 | Nina De Clercq | 3 |
| 8 | Hamid Benali | 2 |
EXISTS kijkt of er iets is
EXISTS (subquery) is waar als de subquery minstens één rij geeft. Wat ze precies selecteert, maakt niet uit, daarom schrijf je vaak SELECT 1.
Hier verwijst de subquery naar de buitenste rij (l.id): per lid kijkt ze of er een openstaande uitlening is. Zo'n subquery heet *gecorreleerd*. NOT EXISTS doet het omgekeerde, en heeft geen last van NULL.
SELECT naam FROM leden l WHERE EXISTS (SELECT 1 FROM uitleningen u WHERE u.lid_id = l.id AND u.teruggebracht_op IS NULL)| naam |
|---|
| Sanne Willems |
| Nina De Clercq |
| Hamid Benali |
| Wout Lambrecht |
| Jonas Verhaeghe |
Probeer het zelf
Welke leden hebben nog nooit iets geleend? Toon hun naam.
Klaar voor meer?
De volledige les heeft 6 oefeningen, van makkelijk naar uitdagend, met hints, punten en een reeks die je kan opbouwen.
Begin aan de les