Vaak is het nodig om queries te formuleren waarbij de filtercriteria dynamisch worden bepaald – de lijst met waarden wordt ingesteld door de interfacegebruiker, en ontbrekende waarden (NULL) moeten ook in de resultaten kunnen verschijnen of niet. Zo'n query moet snel werken bij grote volumes en semantisch correct zijn in termen van SQL.
Onjuist combineren van voorwaarden IN, NOT IN en het controleren op NULL leidt tot onverwachte resultaten omdat in SQL de expressie "NULL IN (...)" altijd UNKNOWN retourneert, en "NOT IN" kan leiden tot een lege uitkomst als een van de elementen in de lijst NULL is. De prestaties bij grote data kunnen aanzienlijk dalen met slecht geschreven voorwaarden.
De juiste combinatie ziet er als volgt uit:
SELECT * FROM sales WHERE region IN ('Moscow','Samara') OR region IS NULL;
SELECT * FROM sales WHERE (region NOT IN ('Moscow','Samara') OR region IS NULL);
SELECT * FROM sales WHERE region NOT IN ('Moscow','Samara') AND region IS NOT NULL;
Belangrijkste punten:
Wat gebeurt er als we "WHERE field NOT IN ('a', NULL)" controleren?
Het resultaat is altijd leeg, omdat elke rij wordt vergeleken met NULL in de lijst, wat UNKNOWN oplevert en alles filtert.
Voorbeeldcode:
SELECT * FROM test WHERE name NOT IN ('Ivan', NULL);
Geeft "IN (NULL,...)" een waarde voor rijen met NULL?
Nee. De expressie NULL IN (...) retourneert altijd UNKNOWN, niet TRUE.
Hoe kun je filtering versnellen op een grote lijst van waarden?
Gebruik indexen en pas bij voorkeur een JOIN met een tijdelijke tabel toe als de lijst groot is (honderden/tientallen waarden) – dit versnelt de filtering in vergelijking met een lange IN.
In een analytisch rapport werd "WHERE city NOT IN ('London', field_2, NULL)" toegepast. Resultaat – volledig lege uitkomst, niemand kon de oorzaak van de verloren rijen begrijpen.
Voordelen:
Nadelen:
In de CRM kozen we een lijst van klantregio's en voegden een extra knop "Inclusief ongevulde waarden" toe. De filterlogica:
... WHERE city IN ('SPB','NNov') OR city IS NULL
Voordelen:
Nadelen: