O HAVING é uma cláusula SQL utilizada para filtrar resultados, assim como WHERE, com a diferença que ele suporta as funções de agregação.

Visão geral

A cláusula HAVING tem sido muito utilizada não só para filtrar resultados com funções de agregação, mas também para filtrar resultados após um agrupamento, o que não é permitido utilizando o WHERE. Outro ponto muito comum é a presença de subqueries como filtro.

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
Tabela 1. Tabela produto
id nome
1 Infantil
2 Informatica
3 Educacional
Tabela 2. Tabela categoria_produto
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
Tabela 3. Tabela venda_produto

Sintaxe

SELECT
  [ coluna1, coluna2, ... | * ]
FROM
  [ tabela1, tabela2, ... ]
GROUP BY
  [ campo1, campo2, ... ]
HAVING
  [ condicao1, condicao2, ... ]

Na prática

Exemplo 1

Suponha que seja necessário listar todos os produtos que foram vendidos no ano de 2018 e que tiveram uma receita maior que 300. Para isso, podemos utilizar a query abaixo:

SELECT 
    P.nome,
    SUM(V.valor) as RECEBIDO
FROM
    produto P, venda_produto V
WHERE
    YEAR(v.Data) = 2018 AND
    P.id = V.id_produto
GROUP BY 
    P.id
HAVING 
    SUM(V.valor) > 300

No trecho de código acima, na linha 3 realizamos a soma da coluna valor da tabela venda_produto, nomeando a coluna no resultado de RECEBIDO.

Na linha 5 informamos que a consulta será realizada em duas tabelas, na tabela produto, nomeada de P, e na tabela venda_produto, nomeada de V.

Na linha 7 filtramos utilizando o WHERE o ano, definindo que somente resultados do ano de 2018 sejam trazidos pela consulta, e em seguida, na linha 8 realizamos o vínculo entre as duas tabelas, definindo que o ID da tabela produto seja o mesmo na tabela venda_produto.

Nas linhas 9 e 10 agrupamos o resultado do produto, para que venha apenas uma ocorrência de cada.

Nas linhas 11 e 12 utilizamos o HAVING para filtrar os depois do agrupamento, definindo que serão trazidos somente resultados que a soma da coluna valor seja maior que 300.

No exemplo acima, utilizamos no HAVING a função SUM, para filtrar com base no resultado de uma soma, o que não é possível fazer utilizando a cláusula WHERE.

O resultado pode ser visto na Tabela 4.

Nome RECEBIDO
Notebook 7000.00
Monitor LG 19 450.00
Tabela 4. Resultado da consulta para listar todos os produtos que foram vendidos no ano de 2018 e que tiveram uma receita maior que 300

Exemplo 2

Como outro exemplo, podemos aproveitar a mesma estrutura de tabelas para realizar outra consulta. Suponha que seja necessário trazer todos os produtos cadastrados e a sua receita total gerada, mas exibir no resultado somente os produtos que tiverem no mínimo duas vendas. Para isso, podemos utilizar a query abaixo:

SELECT 
    P.id,
    P.nome as PRODUTO,
    SUM(V.valor) as RECEITA
FROM 
    produto P, 
    venda_produto V
WHERE 
    P.id = V.id_produto   
GROUP BY
    P.id
HAVING 
    COUNT(V.id_produto) >= 2

No trecho de código acima, na linha 4 solicitamos a soma dos valores da coluna valor da tabela venda_produto, e em seguida, nas linhas 5 a 7 informamos que a consulta será realizada em duas tabelas, na tabela produto, nomeada de P, e na tabela venda_produto, nomeada de V.

Na linha 9 informamos que o id da tabela produto será o mesmo da tabela venda_produto, realizando assim o vínculo entre as duas.

Nas linhas 10 e 11 agrupamos o resultado da consulta pelo id do produto, afinal, precisamos apenas de uma ocorrência e seu valor total de receita;

Nas linhas 12 e 13 utilizamos o HAVING para filtrar o resultado, exibindo somente os resultados que tenham no mínimo duas vendas, utilizando a função COUNT para isso.

O resultado pode ser visto na Tabela 5.

id PRODUTO RECEITA
1 Bola 105.00
2 Patinete 240.00
5 Notebook 7000.00
8 O dia do Curinga 130.00
Tabela 5. Resultado da consulta de todos os produtos, com valores de receita, exibindo somente os que possuem mais de duas vendas

Exemplo 3

Para este exemplo, considere a tabela abaixo, a tabela pessoa (Tabela 6), responsável por manter as informações de todas as pessoas do banco de dados:

id Nome Email
1 Pedro Henrique pedro@gmail.com
2 Thiago Henrique thiago@gmail.com
3 Thiago Henrique thiago@gmail.com
4 Thiago Henrique thiago@gmail.com
5 Gabriel Felipe gabriel@gmail.com
6 Pedro Henrique pedrohenrique@gmail.com
Tabela 6. Estrutura da tabela Pessoa

Suponha que seja necessário trazer todas as pessoas que tenham o nome igual ao nome de outra pessoa no banco de dados, ou seja, trazer apenas homônimos. Para isso podemos utilizar a query abaixo:

SELECT 
    nome 
FROM
    pessoa
GROUP BY
    nome
HAVING 
    COUNT(nome) > 1

No trecho de código acima, nas Linhas 1 a 6 trazemos todas as pessoas do banco de dados, e agrupamos por nome. O diferencial acontece na Linha 7 e 8, onde utilizamos a cláusula HAVING para trazer no resultado, somente os nomes que tenham aparecido no resultado mais de uma vez.

O resultado da query pode ser visto abaixo:

Nome
Pedro Henrique
Thiago Henrique
Tabela 7. Resultado da consulta por homônimos