13.2.11.6 Subquery’s met EXISTS of NOT EXISTS
Als een subquery rijen retourneert, EXISTS
is subquery
TRUE
, en NOT EXISTS
is subquery
FALSE
. Bijvoorbeeld:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Traditioneel begint een EXISTS
subquery met SELECT *
, maar hij zou kunnen beginnen met SELECT 5
of SELECT column1
of wat dan ook. MySQL negeert de SELECT
lijst in zo’n subquery, dus dat maakt geen verschil.
In het voorgaande voorbeeld, als t2
rijen bevat, zelfs rijen met niets anders dan NULL
waarden, is de EXISTS
voorwaarde TRUE
. Dit is eigenlijk een onwaarschijnlijk voorbeeld omdat een EXISTS
subquery bijna altijd correlaties bevat. Hier volgen enkele realistischer voorbeelden:
-
Welk soort winkel is aanwezig in een of meer steden?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
-
Welk soort winkel is in geen enkele stad aanwezig?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
- Welk soort winkel is in alle steden aanwezig?
SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));
Het laatste voorbeeld is een dubbel-nested NOT EXISTS
query. Dat wil zeggen, het heeft een NOT EXISTS
clausule binnen een NOT EXISTS
clausule. Formeel beantwoordt het de vraag “bestaat er een stad met een winkel die niet in Stores
” staat? Maar het is eenvoudiger om te zeggen dat een geneste NOT EXISTS
antwoord geeft op de vraag “is x
TRUE
voor alle y
?”
In MySQL 8.0.19 en later kunt u ook NOT EXISTS
of NOT EXISTS
met TABLE
in de subquery gebruiken, zoals dit:
SELECT column1 FROM t1 WHERE EXISTS (TABLE t2);
De resultaten zijn hetzelfde als bij gebruik van SELECT *
zonder WHERE
clausule in de subquery.