Si una subconsulta retorna algún registro, entonces EXISTS
es subquery
TRUE
, y NOT EXISTS
es subquery
FALSE
. Por ejemplo:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Tradicionalmente, una subconsulta EXISTS
comienza con SELECT *
, pero puede comenzar con SELECT 5
o SELECT col1
o nada. MySQL ignora la lista SELECT
en tales subconsultas, así que no hace distinción.
Para el ejemplo precedente, si t2
contiene algún registro, incluso registros sólo con valores NULL
entonces la condición EXISTS
es TRUE
. Este es un ejemplo poco probable, ya que prácticamente siempre una subconsulta [NOT] EXISTS
contiene correlaciones. Aquí hay algunos ejemplos más realistas:
- ¿Qué clase de tienda hay 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é clase de tienda no hay 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é clase de tienda hay 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 un doblemente anidado NOT EXISTS
. Esto es, tiene una cláusula NOT EXISTS
dentro de otra NOT EXISTS
. Formalmente, responde a la pregunta “¿existe una ciudad con una tienda que no esté en Stores
?” Sin embargo, es más fácil decir que un NOT EXISTS
responde a la pregunta “¿es x TRUE
para todo y?”
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com.