13.2.11.6 Subconsultas com EXISTÊNCIAS ou NÃO EXISTÊNCIAS
Se uma subconsulta devolver qualquer fila, EXISTS
é subquery
TRUE
, e NOT EXISTS
é subquery
FALSE
. Por exemplo:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Tradicionalmente, um EXISTS
subquery começa com SELECT *
, mas poderia começar com SELECT 5
ou SELECT column1
ou seja o que for. O MySQL ignora a lista SELECT
numa tal subconsulta, por isso não faz qualquer diferença.
Para o exemplo anterior, se t2
contiver quaisquer linhas, mesmo linhas sem nada a não ser NULL
valores, o EXISTS
condição é TRUE
. Este é de facto um exemplo improvável porque um EXISTS
subquery quase sempre contém correlações. Aqui estão alguns exemplos mais realistas:
-
Que tipo de loja está presente em uma ou mais cidades?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
-
Que tipo de loja está presente em nenhuma cidade?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
-
Que tipo de loja está presente em todas as cidades?
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));
O último exemplo é uma consulta de duplo registo NOT EXISTS
. Ou seja, tem uma cláusula NOT EXISTS
dentro de uma cláusula NOT EXISTS
. Formalmente, responde à pergunta “existe uma cidade com uma loja que não está em Stores
“? Mas é mais fácil dizer que um aninhado NOT EXISTS
responde à pergunta “é x
TRUE
para todos y
?
No MySQL 8.0.19 e posteriores, também se pode usar NOT EXISTS
ou NOT EXISTS
com TABLE
na subconsulta, desta forma:
SELECT column1 FROM t1 WHERE EXISTS (TABLE t2);
Os resultados são os mesmos que quando se usa SELECT *
sem WHERE
cláusula na subconsulta.