Voltar para a lista de artigos Artigos
16 minutos de leitura

Introdução à cláusula HAVING do SQL: Um tutorial para iniciantes

Então, você é novo no SQL e acabou de se deparar com a cláusula HAVING e acabou de se deparar com a cláusula HAVING. Mas o que ela faz? Por que ela é essencial? Neste artigo, vamos nos aprofundar nos conceitos básicos da cláusula HAVING no SQL. Além disso, faremos exercícios práticos para aprimorar sua compreensão de sua funcionalidade.

Vamos começar definindo Structured Query Language (SQL). A SQL é uma linguagem de programação poderosa e padronizada, projetada especificamente para gerenciar e manipular bancos de dados relacionais; em termos simples, é a forma como nos comunicamos com os bancos de dados que contêm todos os nossos dados importantes. Podemos executar várias tarefas com esses sistemas de banco de dados, inclusive consultar, atualizar e gerenciar dados.

O SQL é essencial para o gerenciamento e a análise eficazes dos dados. Ele permite que nós, como usuários, recuperemos informações específicas, manipulemos dados em bancos de dados e criemos estruturas de banco de dados. O SQL oferece um conjunto avançado de ferramentas para extrair informações relevantes e gerar relatórios na análise de dados. Você pode saber mais sobre esses bancos de dados em nosso artigo O que é um banco de dados SQL?

O SQL tem palavras-chave e cláusulas (comandos) específicas que nos ajudam a realizar essas ações, assim como a gramática e as construções de um idioma escrito. Um exemplo disso é a cláusula HAVING. No SQL, a cláusula HAVING é útil para refinar os resultados da consulta filtrando grupos de dados com base em condições específicas. Neste artigo, examinaremos alguns exercícios para iniciantes com a cláusula HAVING para que você possa começar; para obter uma explicação mais detalhada, consulte nosso artigo A Cláusula SQL HAVING Explicada.

Se você está pensando em iniciar sua jornada no SQL, mas não sabe por onde começar, nosso SQL para Iniciantes curso é um excelente ponto de partida. Neste curso, você aprenderá os fundamentos do SQL recuperando dados de bancos de dados e criando relatórios simples usando exemplos interativos e reais. Então, dito isso, vamos dar uma olhada mais profunda na cláusula SQL HAVING.

A cláusula HAVING

A cláusula HAVING funciona em conjunto com a cláusula GROUP BY para restringir os resultados com base em funções agregadas. As funções de agregação são ferramentas SQL que nos permitem calcular valores como o total (SUM), a média (AVG) e o valor mais baixo (MIN) de grupos de linhas em nossos dados.

Vamos explicar essas cláusulas com um exemplo. Imagine que temos uma tabela sales que armazena os relatórios de vendas de nossa empresa. Podemos usar a seguinte consulta para encontrar regiões com vendas totais superiores a US$ 10.000:

SELECT Region, SUM(TotalSales) as TotalSales
FROM Sales
GROUP BY Region
HAVING SUM(TotalSales) > 10000;

Aqui está o detalhamento:

  • SELECT Region, SUM(TotalSales) as TotalSales: A cláusula SELECT exibe a coluna region e a soma total das vendas.
  • FROM Sales: A cláusula FROM especifica a tabela de origem - aqui, sales.
  • GROUP BY Region: A cláusula GROUP BY agrupa os dados com base na coluna Region. Por exemplo, se tivermos os valores "France", "Italy" e "Spain" na coluna Region, teremos três grupos.
  • HAVING SUM(TotalSales) > 10000: A cláusula HAVING especifica que os dados agregados para esse valor de coluna (ou seja, todas as vendas para "Italy") devem ter um total de vendas superior a $10,000 para serem incluídos em nosso conjunto de resultados. Se o total de vendas de uma região fosse menor que esse valor, ela não apareceria nos resultados da consulta.

Com HAVING, podemos refinar os resultados da consulta filtrando dados agregados (agrupados) com base nas condições que especificamos. Isso permite que os usuários se concentrem em subconjuntos de dados que atendam a critérios específicos, possibilitando a extração de insights significativos dos conjuntos de dados.

Talvez você já tenha ouvido falar que a cláusula WHERE é usada no SQL para filtrar dados. Qual é a diferença entre essas duas cláusulas? Qual delas você deve usar?

No SQL, as cláusulas HAVING e WHERE são importantes para filtrar dados, mas são usadas em diferentes estágios da consulta. Para uma análise mais detalhada, consulte nosso artigo Qual é a diferença entre as cláusulas WHERE e HAVING no SQL? Por enquanto, vamos dar uma olhada em alguns exemplos.

Vamos modificar um pouco a consulta anterior. Desta vez, estamos calculando o total de vendas de cada região em 2023:

SELECT Region,SUM(TotalSales) as TotalSales
FROM Sales
WHERE YEAR(SaleDate) = 2023
GROUP BY Region;
In this version, the WHERE clause filters individual rows before they are grouped to include only those with a sale date in 2023. Now, let’s include both the WHERE and HAVING clauses:
SELECT Region, SUM(TotalSales) as TotalSales
FROM Sales
WHERE YEAR(SaleDate) = 2023
GROUP BY Region
HAVING SUM(TotalSales) > 10000;

Aqui, a cláusula WHERE filtra linhas individuais com base na data de venda. Depois que GROUP BY é aplicada, a cláusula HAVING garante que somente as regiões com vendas totais de mais de US$ 10.000 em 2023 sejam incluídas no resultado final.

Para resumir:

  • WHERE é usada para filtrar linhas individuais, restringindo os dados antes da agregação.
  • HAVING é usado para filtrar grupos de linhas; é aplicado aos grupos criados pela agregação.

Exemplo de consultas com HAVING

A melhor maneira de aprender um idioma é praticar, portanto, nesta seção, veremos alguns exemplos práticos para ajudar a explicar a cláusula HAVING no contexto. Se você for completamente novo em consultas SQL, dê uma olhada na nossa Folha de dicas SQL para Iniciantes para ajudá-lo a navegar pelas consultas a seguir.

Exercício 1: Clientes com mais de uma compra

Exercício: Você tem os dados de compra de uma loja on-line e a equipe de análise da loja deseja identificar os clientes que fizeram várias compras, ou seja, encontrar os clientes que retornaram. Exiba os IDs dos clientes e o número de compras que eles fizeram.

Solução:

SELECT customer_id, COUNT(purchase_id) as purchase_count
FROM purchases
GROUP BY customer_id
HAVING COUNT(purchase_id) > 1;

Solução Explicação:

  • SELECT customer_id, COUNT(purchase_id) as purchase_count: A cláusula SELECT exibe os IDs dos clientes e o número de compras.
  • FROM purchases: Especifica a tabela de origem como purchases.
  • GROUP BY customer_id: Agrupa os dados de compra pelos IDs de clientes, criando um grupo para cada cliente.
  • HAVING COUNT(purchase_id) > 1: A cláusula HAVING filtra o conjunto de resultados, incluindo apenas os clientes que fizeram mais de uma compra.

Resultado:

customer_idpurchase_count
1035
1092
1113

Essa consulta destaca os clientes que fizeram mais de uma compra - ou clientes que retornaram. A cláusula HAVING é fundamental porque filtra os clientes que fizeram uma única compra. Sem HAVING, a consulta retornaria todos os clientes.

Exercício 2: Reconhecendo clientes fiéis

Exercício: O gerente de uma loja de roupas on-line deseja recompensar os clientes que fizeram pelo menos dez compras em 2023. Você foi solicitado a exibir o ID do cliente e o número de pedidos dos clientes que fizeram mais de 10 pedidos no ano passado. Além disso, certifique-se de que o cliente com o maior número de pedidos apareça no topo dos resultados.

Solução:

SELECT customer_id, COUNT(order_id) as order_count
FROM orders
WHERE YEAR(order_date) = 2023
GROUP BY customer_id
HAVING COUNT(order_id) > 10
ORDER BY OrderCount DESC;

Solução Explicação:

  • SELECT customer_id, COUNT(order_id) as OrderCount: A cláusula SELECT exibe o ID do cliente e o número de pedidos.
  • FROM orders: Isso especifica a tabela de origem como orders.
  • WHERE YEAR(order_date) = 2023: Isso filtra as linhas para incluir somente os pedidos de 2023.
  • GROUP BY customer_id: Agrupa os dados pelo ID do cliente, criando um grupo para cada cliente.
  • HAVING COUNT(order_id) > 10: Essa cláusula restringe o conjunto de resultados a clientes com mais de dez pedidos.
  • ORDER BY OrderCount DESC: Classifica os resultados pelo número de pedidos em ordem decrescente (10-1), de modo que o cliente com o maior número de pedidos seja o primeiro.

Saída:

customer_idorder_count
121415
113514
115612

Essa consulta retorna uma lista de clientes que fizeram pelo menos dez compras no ano passado, com o cliente com o maior número de pedidos no topo dos resultados. A cláusula HAVING é importante nesse cenário porque restringe os resultados apenas aos clientes fiéis que fizeram mais de dez pedidos. Sem a cláusula HAVING, a consulta retornaria todos os clientes, independentemente do número de pedidos.

Exercício 3: Principais produtos por vendas

Exercício: O gerente de vendas de uma loja de móveis quer identificar os produtos de maior faturamento. Para produtos com vendas superiores a US$ 10.000, exiba o ID do produto e o valor total vendido. Além disso, certifique-se de que os produtos com as vendas mais altas sejam exibidos na parte superior dos resultados.

Solução:

SELECT product_id, SUM(sales_amount) as total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sales_amount) > 10000
ORDER BY total_sales DESC;

Solução Explicação:

  • SELECT product_id, SUM(sales_amount) as total_sales: A cláusula SELECT exibe o ID do produto e o total de vendas.
  • FROM sales: Isso especifica a tabela de origem como sales.
  • GROUP BY product_id: Isso agrupa os dados pelo ID do produto, criando um grupo para cada produto.
  • HAVING SUM(sales_amount) > 10000: A cláusula HAVING filtra o conjunto de resultados para incluir somente produtos com vendas totais superiores a US$ 10.000.
  • ORDER BY total_sales DESC: Classifica os resultados por total de vendas em ordem decrescente, garantindo que os produtos com mais vendas apareçam primeiro.

Saída:

product_idtotal_sales
10218300
10515600
16012200

Essa consulta retorna uma lista dos produtos de melhor desempenho, exibindo os produtos com vendas superiores a US$ 10.000 e classificando as linhas em ordem decrescente pelo total de vendas.

A cláusula HAVING é necessária aqui porque ela nos permite filtrar o conjunto de resultados usando dados agregados, especificamente o total de vendas. Sem a cláusula HAVING, não seria possível filtrar os resultados com base no total de vendas de cada produto. A cláusula WHERE não é adequada para essa tarefa porque filtra as linhas antes do agrupamento; estamos interessados nas condições aplicadas aos dados agregados após o agrupamento.

Exercício 4: Classificação média por gênero

Exercício: Um crítico de cinema deseja identificar gêneros de filmes com classificações médias altas em 2020. Foi solicitado que você exibisse os gêneros de filmes e as classificações médias para os gêneros com classificação acima de 4,0. Além disso, certifique-se de que os gêneros com as classificações médias mais altas apareçam na parte superior.

Solução:

SELECT genre, AVG(rating) as avg_rating
FROM movies
WHERE YEAR(release_date) = 2020
GROUP BY genre
HAVING AVG(rating) > 4.0
ORDER BY avg_rating DESC;

Explicação:

  • SELECT genre, AVG(rating) as avg_rating: A cláusula SELECT exibe o gênero do filme e a classificação média.
  • FROM movies: especifica a tabela de origem como movies.
  • WHERE YEAR(release_date) = 2020: Filtra as linhas para incluir somente os filmes lançados no ano de 2020.
  • GROUP BY genre (gênero): Agrupa os dados por gênero, criando um grupo para cada gênero.
  • HAVING AVG(rating) > 4.0: Filtra o conjunto de resultados para incluir apenas gêneros com uma classificação média superior a 4,0.
  • ORDER BY avg_rating DESC: Classifica os resultados por classificação média em ordem decrescente, garantindo que os gêneros com as classificações médias mais altas estejam no topo.

Resultado:

genreavg_rating
Drama4.5
Comedy4.2

Essa consulta ajuda o crítico de cinema a identificar gêneros de filmes excepcionais com uma classificação média superior a 4,0 em 2020. O conjunto de resultados inclui cada gênero e sua classificação média, que são classificados em ordem decrescente com base na classificação média.

A cláusula HAVING é essencial porque nos permite filtrar gêneros com base em dados agregados (a classificação média).

Exercício 5: Identificação de usuários com duração de login prolongada

Exercício: Usando os dados de login do usuário de um site, a equipe de segurança de TI procura identificar usuários com durações de login único excepcionalmente longas; isso permite que eles realizem monitoramento e análise de segurança abrangentes. Exiba os nomes dos usuários, os endereços de e-mail e a duração da sessão de login único mais longa. Considere apenas os usuários cujos tempos de login excedam duas horas (7200 segundos). Além disso, certifique-se de que os usuários com as durações de login mais longas apareçam na parte superior dos resultados.

Solução:

SELECT 
  users.user_name, 
  users.email_address, 
  MAX(logins.login_duration) as longest_login_duration
FROM users
JOIN logins 
ON users.user_id = logins.user_id
GROUP BY users.user_name, users.email_address
HAVING MAX(logins.login_duration) > 7200
ORDER BY longest_login_duration DESC;

Explicação:

  • SELECT users.user_name, users.email_address, MAX(logins.login_duration) as longest_login_duration: A cláusula SELECT exibe os nomes de usuários, os endereços de e-mail e a duração da sessão de login única mais longa.
  • FROM users: Isso especifica a tabela de origem como users.
  • JOIN logins ON users.user_id = logins.user_id: Executa uma junção interna entre as tabelas users e logins com base no ID do usuário.
  • GROUP BY users.user_name: Isso agrupa os dados pelos nomes de usuário, criando um grupo para cada usuário.
  • HAVING MAX(logins.login_duration) > 7200: A cláusula HAVING filtra o conjunto de resultados, incluindo apenas usuários com duração de login superior a 2 horas (7200 segundos).
  • ORDER BY longest_login_duration DESC: Ordena o resultado pela duração mais longa do login, em ordem decrescente.

Resultado:

user_nameemail_addresslongest_login_duration
marty_89ff_7799@mail.com9067
scott_32scott_oc@mail.com7591
rachel_2003ray_hhh@mail.com7231

Essa consulta fornece à equipe de segurança de TI os nomes dos usuários, os endereços de e-mail e a duração de suas sessões de login único mais longas. Ela mostra apenas os usuários com durações de login prolongadas para aumentar o escrutínio de segurança.

Nesse caso, a cláusula HAVING é importante porque nos permite filtrar o conjunto de resultados com base em dados agregados, especificamente a duração máxima de login obtida por cada usuário. Como queremos identificar os usuários que fizeram login por mais de duas horas, a cláusula HAVING nos permite impor essa condição à duração máxima do login.

Casos de uso comuns de HAVING

A cláusula HAVING no SQL é uma ferramenta essencial em cenários reais em que a análise de dados, os relatórios e o business intelligence são importantes. Vamos dar uma olhada em alguns casos de uso comuns que demonstram a versatilidade do HAVING.

1. segmentação de clientes

As empresas se beneficiam da compreensão de diferentes grupos de clientes para que possam direcionar seus esforços de marketing. A criação de segmentos de clientes permite estratégias personalizadas, o que aumenta a satisfação do cliente.

Usando o site HAVING, podemos filtrar clientes de alto valor com base em limites de compra:

SELECT customer_id, SUM(purchase_amount) as total_purchase
FROM purchases
GROUP BY customer_id
HAVING SUM(purchase_amount) > 500;

2. análise de desempenho de funcionários

Os profissionais de RH podem usar o SQL para ajudar a avaliar o desempenho dos funcionários. Isso facilita avaliações de desempenho justas e específicas.

Usando a consulta a seguir, podemos encontrar funcionários que concluíram mais do que um determinado número de projetos:

SELECT employee_id, COUNT(project_id) as completed_projects
FROM projects
GROUP BY employee_id
HAVING COUNT(project_id) >= 5;

3. monitoramento de vendas de produtos

Para garantir um gerenciamento eficiente do estoque, as empresas precisam rastrear os produtos com melhor desempenho. Isso pode ajudá-las a identificar os itens mais vendidos e a alocar recursos de forma mais eficaz.

Usando a consulta a seguir, podemos filtrar produtos com vendas que excedam um determinado limite:

SELECT product_id, SUM(sales_quantity) as total_sales
FROM sales	
GROUP BY product_id
HAVING SUM(sales_quantity) > 50;

4. rastreamento de participação em eventos

Os organizadores de eventos podem querer identificar os participantes altamente engajados, ou seja, aqueles que participaram de mais de um evento. Encontrar insights sobre esses participantes pode ajudar no planejamento de eventos futuros.

O uso do site HAVING na consulta a seguir nos permite identificar participantes altamente envolvidos com base em sua contagem de eventos:

SELECT attendee_id, COUNT(event_id) as attended_events
FROM event_attendance
GROUP BY attendee_id
HAVING COUNT(event_id) > 3;

5. controle de qualidade na fabricação

Na fabricação, o controle de qualidade é essencial para produzir produtos de alta qualidade. Ao especificar limites em suas consultas SQL, a equipe pode garantir a qualidade de seus produtos.

Usando HAVING na consulta a seguir, podemos identificar produtos com taxas de defeitos inferiores ao limite especificado:

SELECT product_id, AVG(defect_rate) as avg_defect_rate
FROM manufacturing_quality
GROUP BY product_id
HAVING AVG(defect_rate) > 0.02;

Dicas de solução de problemas para a cláusula HAVING

O uso da cláusula HAVING no SQL pode, às vezes, resultar em erros comuns, especialmente se você estiver apenas começando. Aqui estão algumas dicas de solução de problemas para resolver possíveis problemas:

Ordem das instruções SQL

Ao começar a usar as consultas SQL, é comum cometer erros na ordem das instruções. Certifique-se sempre de que sua consulta siga essa ordem:

SELECT column1, COUNT(column2) as count_column2
FROM my_table
WHERE condition
GROUP BY column1
HAVING COUNT(column2) > 10
ORDER BY column1;

Não agrupamento de dados

Ao usar a cláusula HAVING, os dados devem primeiro ser agrupados usando a cláusula GROUP BY. A consulta a seguir resultaria em um erro porque não tem GROUP BY:

SELECT category, COUNT(product_id) as product_count
FROM products
HAVING COUNT(product_id) > 5;

Inconsistência de SELECT e GROUP BY

A coluna não agregada na instrução SELECT deve ser incluída na cláusula GROUP BY. O exemplo abaixo demonstra que, como a categoria não é agregada, ela deve ser incluída na cláusula GROUP BY.

SELECT category, COUNT(product_id) as product_count
FROM products
GROUP BY category
HAVING COUNT(product_id) > 5;

Uso incorreto de condições HAVING

A consulta a seguir será executada sem erros, mas não segue as práticas recomendadas. A cláusula HAVING é usada para filtrar resultados com base em valores agregados; portanto, a inclusão de colunas não agregadas ou condições incorretas contradiz a finalidade pretendida.

SELECT category, COUNT(product_id) as product_count
FROM products
GROUP BY category
HAVING category = 'Electronics';

Embora a consulta seja executada com êxito, é recomendável usar a cláusula WHERE para filtrar colunas não agregadas. Isso está em conformidade com as práticas recomendadas e garante a clareza do seu código SQL.

WHERE vs. HAVING

Podem ocorrer erros como resultado da confusão entre WHERE e HAVING. Para evitar isso, lembre-se de que WHERE é para linhas e HAVING é para grupos.

Na consulta anterior com o erro, poderíamos usar mais apropriadamente WHERE em vez de HAVING:

SELECT category, COUNT(product_id) as product_count
FROM products
WHERE category = 'Electronics'
GROUP BY category;

Exclusão de funções agregadas de HAVING

Ao filtrar com base em valores agregados, lembre-se de incluir a função agregada na cláusula HAVING. No exemplo a seguir, product_id deveria ser COUNT(product_id) na cláusula HAVING:

SELECT category, COUNT(product_id)
FROM products
GROUP BY category
HAVING product_id > 5;

Há muitos outros erros de sintaxe SQL possíveis. A boa notícia é que, com a prática, você aprenderá rapidamente a evitá-los. Quando encontrar um erro, preste atenção à mensagem de erro, que pode ajudá-lo a identificar o problema específico.

Pronto para praticar a cláusula HAVING do SQL?

A cláusula SQL HAVING é uma ferramenta valiosa para otimizar os resultados de consultas em análises de dados, relatórios e Business Intelligence. O domínio dessa cláusula permite que os usuários de SQL extraiam insights valiosos de dados agregados.

À medida que você avança em sua jornada SQL, não tenha medo de cometer erros ao escrever consultas com a cláusula HAVING; tudo isso faz parte do processo de aprendizado! A boa notícia é que você não está sozinho. Há muito material disponível em LearnSQL.com.br para ajudá-lo a dominar a cláusula HAVING. Para obter mais exemplos, consulte nosso tutorial SQL HAVING.

Para ir ainda mais longe, confira nossa trilha SQL de A a Z . Ele abrange tudo o que o SQL tem a oferecer, inclusive a importantíssima cláusula HAVING. Esse curso permite combinar o conhecimento teórico com a prática, escrevendo suas próprias consultas SQL em um console interativo e recebendo feedback instantâneo. Então, o que está esperando? Vamos começar!