13.2.11.6 Subconsultas com EXISTÊNCIAS ou NÃO EXISTÊNCIAS
Se uma subconsulta devolver qualquer fila, EXISTS é subqueryTRUE, e NOT EXISTS é subqueryFALSE. 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 “é xTRUE 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.