🙏 Obrigado pelo apoio. No mês passado, recebemos apenas US$ 32. Isso cobre os servidores, mas não o desenvolvimento, então não haverá novas lições nem recursos este mês. Se puder, contribua para o próximo mês. Apoiar →
Código SQL copiado para a área de transferência

Tempo de leitura: ~7 minutos

Quando voce usa GROUP BY com agregacoes, frequentemente precisa filtrar grupos por seus resultados agregados. HAVING e o operador para filtrar grupos, assim como WHERE filtra linhas individuais. Nesta licao, voce aprendera as diferencas entre WHERE e HAVING, sintaxe e exemplos praticos com Sakila. Ao final, usara HAVING com confianca para analise profunda de dados.

Filtrando Grupos com HAVING

Nas licoes anteriores, voce aprendeu GROUP BY para agrupar dados e aplicar agregacoes. Agora vem o proximo passo: filtrar os proprios grupos por condicoes em valores agregados.

HAVING faz isso permitindo condicoes apos agrupamento.

WHERE vs HAVING

  • WHERE filtra linhas antes do agrupamento
  • HAVING filtra grupos apos agregacao
SELECT coluna1, COUNT(*) AS cnt
FROM tabela
WHERE coluna1 > 100          -- filtrar ANTES do agrupamento
GROUP BY coluna1
HAVING COUNT(*) > 10;        -- filtrar APOS o agrupamento

Sintaxe do HAVING

Estrutura basica:

SELECT coluna1, FUNCAO_AGG(coluna2)
FROM tabela
GROUP BY coluna1
HAVING condicao;

A condicao em HAVING normalmente envolve uma funcao de agregacao.


Exemplos com Uma Condicao

Clientes com pagamentos totais acima de 100

SELECT customer_id, SUM(amount) AS total_paid
FROM payment
GROUP BY customer_id
HAVING SUM(amount) > 100;

Resultado: apenas clientes cujos pagamentos totais excedem 100.

Funcionarios que processaram mais de 50 pagamentos

SELECT staff_id, COUNT(*) AS payments_count
FROM payment
GROUP BY staff_id
HAVING COUNT(*) > 50;

Resultado: funcionarios com mais de 50 pagamentos processados.

Clientes com pagamento medio >= 5

SELECT customer_id, AVG(amount) AS avg_payment
FROM payment
GROUP BY customer_id
HAVING AVG(amount) >= 5;

Resultado: clientes cuja media de pagamento e de pelo menos 5.


HAVING com Multiplas Condicoes

Voce pode combinar condicoes usando AND e OR:

SELECT staff_id, COUNT(*) AS cnt, SUM(amount) AS total
FROM payment
GROUP BY staff_id
HAVING COUNT(*) > 50 AND SUM(amount) > 500;

Resultado: funcionarios com mais de 50 pagamentos E total acima de 500.

Com operador OR

SELECT customer_id, COUNT(*) AS rentals, SUM(amount) AS paid
FROM payment
GROUP BY customer_id
HAVING COUNT(*) > 100 OR SUM(amount) > 1000;

Resultado: clientes com mais de 100 pagamentos OU total acima de 1000.


Exemplos Praticos

Categorias de filmes com vendas acima de 2000

SELECT category_id, SUM(p.amount) AS total_sales
FROM payment p
JOIN rental r ON p.rental_id = r.rental_id
JOIN inventory i ON r.inventory_id = i.inventory_id
JOIN film_category fc ON i.film_id = fc.film_id
GROUP BY category_id
HAVING SUM(p.amount) > 2000;

Paises com mais de 20 clientes

SELECT country, COUNT(*) AS customers_count
FROM customer cu
JOIN address a ON cu.address_id = a.address_id
JOIN city ci ON a.city_id = ci.city_id
JOIN country co ON ci.country_id = co.country_id
GROUP BY country
HAVING COUNT(*) > 20;

Lojas com receita diaria acima de 500

SELECT store_id, DATE(payment_date) AS pay_date, SUM(amount) AS daily_revenue
FROM payment
GROUP BY store_id, DATE(payment_date)
HAVING SUM(amount) > 500;

Perguntas Frequentes

Por que nao posso usar WHERE em vez de HAVING?

WHERE funciona antes do agrupamento, entao nao pode verificar funcoes de agregacao. HAVING funciona apos agrupamento e pode analisar resultados de agregacao (COUNT, SUM, AVG, etc.).

Posso usar uma coluna nao agregada em HAVING?

Sim, voce pode usar uma coluna do GROUP BY, mas geralmente nao e necessario. Por exemplo, HAVING customer_id > 100 funciona, mas e mais natural escrever isso em WHERE antes do agrupamento.

HAVING pode ser usado sem GROUP BY?

Tecnicamente em alguns SGBDs isso e possivel, mas e impratico pois HAVING foi projetado para filtrar grupos. Use WHERE para filtrar linhas individuais sem agrupamento.


Perguntas de Entrevista

O que e HAVING e como difere de WHERE?

HAVING filtra grupos apos agregacao, enquanto WHERE filtra linhas antes do agrupamento. WHERE nao pode funcionar com funcoes de agregacao, mas HAVING funciona apenas com elas.

Posso usar WHERE e HAVING juntos em uma consulta?

Sim, e ate recomendado. WHERE filtra linhas antes do agrupamento e HAVING filtra grupos apos. Por exemplo, WHERE amount > 10 GROUP BY customer_id HAVING SUM(amount) > 100 primeiro exclui pequenos pagamentos, depois agrupa e filtra grupos.

Qual e a ordem de execucao: WHERE ou HAVING?

WHERE e aplicado primeiro (antes de GROUP BY), depois GROUP BY executa agrupamento, depois HAVING filtra grupos resultantes, e finalmente ORDER BY e LIMIT sao aplicados.


Principais conclusoes desta licao:

  • HAVING filtra grupos apos agregacao, WHERE filtra linhas antes do agrupamento.
  • HAVING e usado com funcoes de agregacao (COUNT, SUM, AVG, MIN, MAX).
  • Voce pode combinar multiplas condicoes em HAVING usando AND/OR.
  • Frequentemente WHERE e HAVING trabalham juntos: WHERE exclui linhas indesejadas, HAVING filtra grupos.
  • HAVING permite consultas analiticas profundas com filtragem no nivel do grupo.

Na proxima licao, exploraremos ORDER BY para ordenar resultados.

Tente resolver as tarefas a seguir para reforcar o que voce aprendeu nesta licao.

  1. Encontre nomes duplicados de atores
  2. Encontre categorias de filmes longos
  3. Obtenha uma lista de atores - nomes homônimos