O operador EXISTS é utilizado para verificar se uma subconsulta retorna algum registro.
Ele retorna verdadeiro quando a consulta interna encontra pelo menos um resultado.
SELECT coluna
FROM tabela1
WHERE EXISTS
(
SELECT *
FROM tabela2
WHERE condição
);
CLIENTES
+----+----------+
| ID | Nome |
+----+----------+
| 1 | Ana |
| 2 | Carlos |
| 3 | Pedro |
+----+----------+
PEDIDOS
+----+------------+-------+
| ID | Cliente_ID | Valor |
+----+------------+-------+
| 1 | 1 | 500 |
| 2 | 2 | 700 |
+----+------------+-------+
Buscar clientes que possuem pedidos cadastrados.
SELECT nome
FROM clientes c
WHERE EXISTS
(
SELECT *
FROM pedidos p
WHERE p.cliente_id = c.id
);
Ana
Carlos
Pedro não aparece porque não possui pedidos.
| EXISTS | IN |
|---|---|
| Verifica existência | Compara valores |
| Retorna verdadeiro/falso | Retorna correspondências |
| Pode ser melhor em grandes tabelas | Útil para listas pequenas |
O EXISTS também pode ser combinado com NOT para encontrar registros sem relacionamento.
SELECT nome
FROM clientes c
WHERE NOT EXISTS
(
SELECT *
FROM pedidos p
WHERE p.cliente_id = c.id
);
Retorna clientes que não possuem pedidos.
Uma subconsulta correlacionada utiliza valores da consulta externa.
SELECT
c.nome
FROM clientes c
WHERE EXISTS
(
SELECT 1
FROM pedidos p
WHERE p.cliente_id = c.id
);
Dentro do EXISTS, normalmente utilizamos SELECT 1 porque o conteúdo retornado não importa.
SELECT 1
FROM pedidos
WHERE cliente_id = 1;
O banco apenas verifica se existe algum registro.
| Sistema | Utilização |
|---|---|
| E-commerce | Clientes que compraram |
| Banco | Contas com movimentação |
| Escola | Alunos matriculados |
| RH | Funcionários ativos |
| Erro | Problema |
|---|---|
| Usar EXISTS para retornar dados | Uso incorreto |
| Esquecer relacionamento | Resultado errado |
| Subconsulta sem índice | Baixa performance |
| Confundir com IN | Consulta diferente |