13.2.11.6 Subconsultas con EXISTS o NOT EXISTS
Si una subconsulta devuelve alguna fila, EXISTS
es subquery
TRUE
, y NOT EXISTS
es subquery
FALSE
. Por ejemplo:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Tradicionalmente, una EXISTS
subconsulta comienza con SELECT *
, pero puede comenzar con SELECT 5
o SELECT column1
o cualquier cosa. MySQL ignora la lista SELECT
en dicha subconsulta, por lo que no hay diferencia.
Para el ejemplo anterior, si t2
contiene cualquier fila, incluso filas con nada más que valores NULL
, la condición EXISTS
es TRUE
. En realidad, este es un ejemplo poco probable porque una EXISTS
subconsulta casi siempre contiene correlaciones. He aquí algunos ejemplos más realistas:
- ¿Qué tipo de tienda está presente en una o más ciudades?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
- ¿Qué tipo de tienda está presente en ninguna ciudad?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
¿Qué tipo de tienda está presente en todas las ciudades?
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));
El último ejemplo es una consulta de doble anidamiento NOT EXISTS
. Es decir, tiene una cláusula NOT EXISTS
dentro de una cláusula NOT EXISTS
. Formalmente, responde a la pregunta «¿existe una ciudad con una tienda que no está en Stores
«? Pero es más fácil decir que un NOT EXISTS
anidado responde a la pregunta «¿existe x
TRUE
para todo y
?».
En MySQL 8.0.19 y posteriores, también puedes utilizar NOT EXISTS
o NOT EXISTS
con TABLE
en la subconsulta, así:
SELECT column1 FROM t1 WHERE EXISTS (TABLE t2);
Los resultados son los mismos que cuando se utiliza SELECT *
sin la cláusula WHERE
en la subconsulta.