O EXISTS é uma cláusula SQL que testa quando há um ou mais resultados em uma SUBQUERY e retorna o valor TRUE, permitindo filtrar colunas dentro de uma subconsulta.
Guia do artigo:
Visão geral
A cláusula EXISTS faz uma verificação se existe algum resultado para a subquery informada. Caso haja, o resultado da consulta principal é exibido. É muito comum sua utilização quando se deseja trazer resultados onde um valor específico existe dentro de outra tabela.
Para os exemplos a seguir, considere a estrutura de tabelas abaixo, onde temos uma tabela chamada produto (Tabela 1), responsável por armazenar todos os produtos do estoque do cliente, a tabela categoria_produto (Tabela 2), responsável por armazenar todas as categorias existentes no banco de dados, e a tabela venda_produto (Tabela 3), que relaciona os produtos que foram vendidos.
id | nome | preco | Id_categoria |
---|---|---|---|
1 | Bola | 35.00 | 1 |
2 | Patinete | 120.00 | 1 |
3 | Carrinho | 15.00 | 1 |
4 | Skate | 296.00 | 1 |
5 | Notebook | 3500.00 | 2 |
6 | Monitor LG 19 | 450.00 | 2 |
7 | O Diário de Anne Frank | 45.00 | 3 |
8 | O dia do Curinga | 65.00 | 3 |
9 | O mundo de Sofia | 48.00 | 3 |
10 | Através do Espelho | 38.00 | 3 |
id | nome |
---|---|
1 | Infantil |
2 | Informatica |
3 | Educacional |
id | id_produto | valor | data |
---|---|---|---|
1 | 1 | 35.00 | 2018-05-15 |
2 | 1 | 35.00 | 2018-06-15 |
3 | 1 | 35.00 | 2018-07-15 |
4 | 2 | 120.00 | 2018-07-15 |
5 | 2 | 120.00 | 2018-07-14 |
6 | 3 | 15.00 | 2018-07-15 |
7 | 7 | 45.00 | 2018-07-15 |
8 | 8 | 65.00 | 2018-07-15 |
9 | 8 | 65.00 | 2018-07-16 |
10 | 9 | 48.00 | 2018-07-16 |
11 | 5 | 3500.00 | 2018-07-16 |
12 | 5 | 3500.00 | 2018-07-16 |
13 | 6 | 450.00 | 2018-07-16 |
Sintaxe
SELECT
[ coluna1, coluna2, ... | * ]
FROM
[ tabela1, tabela2, ... ]
WHERE
EXISTS (
SELECT
[ coluna1, coluna2, ... | * ]
FROM
[ tabela1, tabela2, ... ]
WHERE [ condicao ]
)
Na prática
Exemplo 1
Suponhamos que seja necessário trazer em uma consulta na tabela de produtos, todos aqueles registros que tiveram alguma venda. Para isso podemos utilizar o EXISTS, que além de testar se a condição é verdadeira, traz como retorno os dados da consulta. Observe a query abaixo:
SELECT
P.ID,
P.nome
FROM
produto P
WHERE
EXISTS (
SELECT
V.ID_PRODUTO
FROM
venda_produto V
WHERE
V.ID_PRODUTO = P.ID
)
Observe que no trecho de código acima, nas linhas 2 e 3 selecionamos o ID e o nome do produto, e em seguida, na linha 5 definimos que a consulta será feita na tabela produto, porém, com a condição de que na linha 7 tenhamos um resultado true, ou seja, que a consulta que busque produtos que tenha sido vendidos na tabela venda_produto tenha encontrado pelo menos 1 produto. Caso encontre, esse resultado é entregue na consulta, conforme ilustra Tabela 4.
id | nome |
---|---|
1 | Bola |
2 | Patinete |
3 | Carrinho |
5 | Notebook |
6 | Monitor LG 19 |
7 | O Diário de Anne Frank |
8 | O dia do Curinga |
9 | O mundo de Sofia |
Repare que antes do nome de cada campo nós inserimos uma letra seguida de ponto, por exemplo: P.ID, P.nome e V.ID_PRODUTO. Esse conceito é chamado de alias.
O alias consiste em apelidar uma tabela. Ele é criado depois do nome da tabela, por exemplo, produtos P e venda_produto V. Nesse caso estamos dizendo que P é o apelido da tabela produtos e V é o apelido da a tabela venda_produto.
Ao utilizar alias fica mais claro de qual coluna estamos nos referindo, por exemplo, sabemos que P.ID está referenciando a coluna ID da tabela produtos e que V.ID_PRODUTO está referenciando a coluna ID_PRODUTO da tabela venda_produto.
Exemplo 2
Neste exemplo utilizaremos o NOT EXISTS para trazer o resultado contrário a primeira query feita no Exemplo 1. Suponhamos que seja necessário trazer da tabela produtos todos os registros que não tiveram nenhuma venda. Para isso podemos utilizar a query abaixo:
SELECT
P.ID,
P.nome
FROM
produto P
WHERE
NOT EXISTS (
SELECT
V.ID_PRODUTO
FROM
venda_produto V
WHERE
V.ID_PRODUTO = P.ID
)
A query acima traz o resultado ilustrado na Tabela 5.
id | nome |
---|---|
4 | Skate |
10 | Através do Espelho |
Exemplo 3
Para o exemplo a seguir, considere a estrutura de tabelas abaixo, onde temos a tabela projeto (Tabela 6), responsável por manter todos os projetos da empresa, e a tabela comentario (Tabela 7), responsável por manter todos os comentários referentes aos projetos cadastrados no banco de dados.
ID | Titulo | Data |
---|---|---|
7 | Criando uma aplicação com React | 2018-04-10 |
8 | API RestFUL com Lumen | 2018-05-10 |
9 | Consumindo uma API RestFUL com Laravel | 2018-05-20 |
10 | Documentação SQL | 2018-05-21 |
ID | Comentario | Data | id_projeto |
---|---|---|---|
1 | Muito legal essa aplicação! Adorei usar o React | 2018-04-10 | 7 |
2 | React é muito simples! Curti o projeto! parabéns! | 2018-05-10 | 7 |
3 | Muito top! | 2018-05-20 | 9 |
4 | Parabéns aos envolvidos! | 2018-05-20 | 9 |
5 | Muito legal, sempre gostei do Laravel. | 2018-05-20 | 9 |
6 | Interessante a forma de recueprar as informações. Não sabia. Gostei! | 2018-05-21 | 9 |
7 | Consigo fazer o mesmo com CodeIgniter? | 2018-05-22 | 9 |
8 | React é apenas JavaScript, há uma API bem pequena para aprender, apenas algumas funções e como usá-las. Depois disso, suas habilidades em JavaScript serão o que te farão um melhor desenvolvedor React | 2018-05-23 | 7 |
Suponha que seja necessário trazer todos os projetos que tenham algum comentário cadastrado. Para isso podemos utilizar a query abaixo:
SELECT
P.id,
P.titulo
FROM
projetos P
WHERE
EXISTS (
SELECT
C.id_projeto
FROM
comentario C
WHERE
C.id_projeto = P.id
)
Observe que selecionamos o id e o titulo do projeto e logo na Linha 7 utilizamos a cláusula EXISTS para verificar se existem valores no resultado da subquery da Linha 9. Das Linhas 9 a 14 realizamos uma subquery na tabela comentario, solicitando somente aqueles que o id do projeto seja igual ao campo id_projeto da tabela comentario.
O resultado obtido pode ser visto na abaixo, na Tabela 8:
ID | Titulo |
---|---|
7 | Criando uma aplicação com React |
9 | Consumindo uma API RestFUL com Laravel |