0Pricing
SQL Interview Prep · Aula

HAVING versus WHERE

Compare a filtragem antes e depois do agrupamento e descubra qual cláusula enxerga a agregação.

HAVING versus WHERE é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.

A Pergunta que Será Feita

“Qual é a diferença entre WHERE e HAVING?” é uma das perguntas mais frequentes em entrevistas de SQL. Uma resposta fraca diz: “HAVING é usado para agregados”. Uma resposta forte explica quando cada cláusula é executada no fluxo de execução da consulta.

Esse momento é o ponto central: WHERE filtra as linhas antes do agrupamento; HAVING filtra os grupos depois da agregação.

Onde Elas se Encaixam na Ordem de Execução

Relembre a ordem lógica de execução de uma consulta:

  • FROM / JOIN → cria o conjunto de linhas
  • WHERE → filtra linhas individuais
  • GROUP BY → transforma as linhas em grupos
  • HAVING → filtra os grupos
  • SELECT → projeta as colunas
  • ORDER BY → ordena

WHERE acontece antes de os grupos existirem; HAVING acontece depois, por isso HAVING pode acessar agregados e WHERE não.

WHERE Não Pode Acessar Agregados

Como WHERE é executado antes do agrupamento, ele ainda não tem valores agregados. Escrever WHERE COUNT(*) > 5 causa um erro de sintaxe em qualquer banco de dados compatível com o padrão.

Entrevistadores inserem exatamente essa linha para verificar se você entende o fluxo de execução. O agregado ainda não existe quando WHERE é avaliado.

-- ERROR: aggregate not allowed in WHERE
SELECT department, COUNT(*)
FROM employees
WHERE COUNT(*) > 5
GROUP BY department;

HAVING Filtra os Grupos

Mova a condição do agregado para HAVING e ela funcionará, porque HAVING é executado depois que os grupos e seus agregados são calculados.

Interprete assim: “agrupe os funcionários e, depois, mantenha apenas os departamentos cuja contagem seja maior que cinco”.

SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;

Coloque os Filtros de Linhas em WHERE

O erro inverso é filtrar linhas brutas em HAVING. Isso geralmente produz a resposta certa, mas é mais lento e enganoso, porque você agrupou linhas que pretendia descartar.

Regra prática: filtre por um valor de uma coluna bruta → WHERE. Filtre por um agregado → HAVING. Filtrar as linhas mais cedo reduz os dados que o agrupamento precisa processar.

-- Better: drop inactive rows BEFORE grouping
SELECT department, COUNT(*) AS headcount
FROM employees
WHERE status = 'active'
GROUP BY department
HAVING COUNT(*) > 5;

As Duas Cláusulas Juntas

Uma consulta completa frequentemente usa ambas. WHERE restringe as linhas primeiro; HAVING então mantém os grupos que atendem aos critérios. Ler de cima para baixo corresponde à ordem lógica.

Exemplo resolvido: entre os pedidos feitos neste ano, encontre os clientes que gastaram mais de 1000 no total.

SELECT customer_id, SUM(amount) AS total_spent
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY customer_id
HAVING SUM(amount) > 1000;

HAVING em Colunas Não Agregadas

HAVING pode fazer referência a uma coluna de agrupamento, não apenas a agregados. HAVING department = 'Sales' é válido, mas não faz sentido: esse filtro deve ficar em WHERE para ser executado mais cedo.

Se um entrevistador mostrar um HAVING que filtra uma coluna simples agrupada, a crítica esperada é: “mova-o para WHERE por eficiência”.

-- Works but inefficient; prefer WHERE department = 'Sales'
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING department = 'Sales';

HAVING sem GROUP BY

Um caso sutil: HAVING é válido mesmo sem GROUP BY. A tabela inteira se torna um único grupo implícito, e HAVING filtra esse grupo.

Se a condição do agregado for falsa, você obterá zero linhas; se for verdadeira, uma linha. É raramente útil, mas entrevistadores perguntam sobre isso para confirmar que você entende o conceito de grupo implícito.

-- Returns the count only if the table has > 100 rows
SELECT COUNT(*) AS total
FROM orders
HAVING COUNT(*) > 100;

HAVING Pode Usar um Alias de SELECT?

Assim como no caso do escopo de alias visto em outro contexto, os dialetos diferem. Postgres e MySQL permitem que HAVING faça referência a um alias de SELECT; SQL Server e Oracle não permitem.

O hábito portável é repetir a expressão do agregado em HAVING. Isso funciona em todos os mecanismos e evita surpresas em uma entrevista que envolva vários bancos de dados.

-- Portable: repeat the aggregate, do not rely on the alias
SELECT region, SUM(amount) AS total
FROM sales
GROUP BY region
HAVING SUM(amount) > 5000;

Perspectiva de Desempenho

Para causar uma boa impressão, relacione as cláusulas ao desempenho: WHERE reduz as linhas que o mecanismo de agrupamento precisa examinar e pode usar índices; HAVING é executado sobre grupos já agregados, portanto não consegue reduzir o custo do agrupamento.

A conclusão que os entrevistadores esperam: aplique cada filtro o mais cedo possível. Somente condições que realmente dependem de um agregado precisam de HAVING.

A Resposta em Uma Frase

Memorize isto para a entrevista: “WHERE filtra as linhas antes do agrupamento e não pode acessar agregados; HAVING filtra os grupos depois da agregação e é a única cláusula que pode testar um valor agregado.”

Em seguida, apresente a lista da ordem de execução e você terá dado uma resposta completa e com tom de profissional experiente.

Verificação rápida

Decida a qual cláusula cada condição pertence.

Recapitulação

WHERE: filtra as linhas antes de GROUP BY; agregados não são permitidos. HAVING: filtra os grupos depois da agregação; é o único lugar onde uma condição de agregado é válida.

  • Coloque os filtros de colunas brutas em WHERE para obter mais velocidade e usar índices.
  • HAVING pode fazer referência a colunas agrupadas, mas não deve ser usado para filtros simples.
  • HAVING funciona sem GROUP BY sobre o grupo implícito formado pela tabela inteira.
  • Repita as expressões de agregados em HAVING para garantir compatibilidade entre dialetos.

Perguntas Frequentes

A aula “HAVING versus WHERE” é grátis?

Sim — o texto completo de “HAVING versus WHERE” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.

O que vou aprender em “HAVING versus WHERE”?

Compare a filtragem antes e depois do agrupamento e descubra qual cláusula enxerga a agregação. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Interview Prep?

Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “HAVING versus WHERE”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Interview Prep?

Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. A regra de GROUP BY para colunas SELECT
  2. HAVING versus WHERE
  3. Agrupando por várias colunas e expressões
  4. Contando e filtrando grupos
← Voltar para SQL Interview Prep