Funções de Agregação

Funções de Agregação

🌍 Analogia do Mundo Real

Imagine que você é um gerente de supermercado olhando uma pilha de recibos de vendas:

Funções de agregação são as "calculadoras" do SQL, ajudando você a calcular rapidamente resultados resumidos a partir de grandes volumes de dados.


🎯 Conceitos Fundamentais

COUNT — Contagem

COUNT é usado para contar linhas. Existem duas formas comuns:

SQL
-- COUNT(*): Conta todas as linhas (incluindo linhas com NULL)
SELECT COUNT(*) AS total_funcionarios FROM employees;

-- COUNT(nome_coluna): Conta linhas onde a coluna não é NULL
SELECT COUNT(email) AS tem_email FROM employees;
Sintaxe Descrição
COUNT(*) Conta todas as linhas, independentemente de NULL
COUNT(nome_coluna) Conta apenas linhas onde a coluna não é NULL
COUNT(DISTINCT nome_coluna) Conta valores distintos não-NULL na coluna

SUM — Soma

Calcula o total de uma coluna numérica, ignorando automaticamente valores NULL.

SQL
SELECT SUM(salary) AS salario_total FROM employees;

AVG — Média

Calcula a média de uma coluna numérica, ignorando automaticamente valores NULL (NULLs não são incluídos no cálculo).

SQL
SELECT AVG(salary) AS salario_medio FROM employees;

MAX / MIN — Máximo / Mínimo

Encontra o valor máximo ou mínimo em uma coluna, ignorando automaticamente valores NULL.

SQL
SELECT MAX(salary) AS maior, MIN(salary) AS menor FROM employees;

Funções de Agregação e Comportamento com NULL

Esta é a armadilha mais comum para iniciantes:

Função Como lida com NULL
COUNT(*) NULL é contado (conta linhas)
COUNT(nome_coluna) Ignora NULL
SUM(nome_coluna) Ignora NULL
AVG(nome_coluna) Ignora NULL (denominador exclui linhas NULL)
MAX(nome_coluna) Ignora NULL
MIN(nome_coluna) Ignora NULL
SQL
-- Suponha que a tabela employees tem 10 linhas, com 3 NULLs na coluna email
SELECT COUNT(*) AS total,        -- 10
       COUNT(email) AS tem_email -- 7
FROM employees;
⚠️ Nota: Ao calcular AVG, o denominador é o número de linhas não-NULL, não o número total de linhas. Se 2 de 5 funcionários têm salários NULL, AVG(salary) calcula a média usando apenas os 3 salários não-NULL.

Desduplicação com DISTINCT em Agregação

Usar DISTINCT dentro de funções de agregação remove duplicatas antes de agregar:

SQL
-- Quantos departamentos distintos possuem funcionários?
SELECT COUNT(DISTINCT department_id) AS qtd_dept FROM employees;

-- Soma de todos os salários distintos (soma desduplicada)
SELECT SUM(DISTINCT salary) AS soma_salarios_unicos FROM employees;

📝 Sintaxe Básica

SQL
-- Sintaxe básica de função de agregação
SELECT funcao_agregacao(nome_coluna) AS alias
FROM nome_tabela
WHERE condicao;

-- Múltiplas funções de agregação podem ser usadas simultaneamente
SELECT COUNT(*) AS contagem_total,
       SUM(nome_coluna) AS soma_total,
       AVG(nome_coluna) AS media,
       MAX(nome_coluna) AS maximo,
       MIN(nome_coluna) AS minimo
FROM nome_tabela;

-- Desduplicação com DISTINCT em agregação
SELECT COUNT(DISTINCT nome_coluna) AS contagem_distinta
FROM nome_tabela;
💡 Dica:

  • Funções de agregação são tipicamente usadas com GROUP BY (abordado na próxima lição), mas também podem ser usadas sozinhas (agregando a tabela inteira)
  • Funções de agregação não podem ser usadas diretamente em condições WHERE — use HAVING em vez disso (abordado mais tarde)
  • NULL é automaticamente ignorado em operações de agregação — isso é tanto uma característica quanto uma armadilha, então fique atento

📌 Exemplos

Exemplo: Estatísticas Básicas de Funcionários

SQL
SELECT COUNT(*) AS total_funcionarios,
       COUNT(email) AS tem_email,
       SUM(salary) AS salario_total,
       AVG(salary) AS salario_medio,
       MAX(salary) AS maior_salario,
       MIN(salary) AS menor_salario
FROM employees;
▶ Experimente

Saída:

TEXT
total_funcionarios  tem_email  salario_total  salario_medio  maior_salario  menor_salario
------------------  ---------  -------------  -------------  -------------  -------------
8                   7          112000.00      14000.00       20000.00       9000.00
💡 Interpretação: Dos 8 funcionários, 7 possuem endereços de e-mail (1 tem e-mail NULL). O salário médio é 14000.


Exemplo: Agregação Condicional + DISTINCT

SQL
-- Quantos funcionários estão no departamento de Tecnologia? Quantos salários distintos?
SELECT COUNT(*) AS qtd_dept_tecnologia,
       COUNT(DISTINCT salary) AS qtd_salarios_distintos,
       AVG(salary) AS salario_medio_tecnologia
FROM employees
WHERE department_id = 1;
▶ Experimente

Saída:

TEXT
qtd_dept_tecnologia  qtd_salarios_distintos  salario_medio_tecnologia
-------------------  ----------------------  ------------------------
3                    3                       17666.67
💡 Interpretação: O departamento de Tecnologia tem 3 funcionários com 3 salários distintos, e um salário médio de 17666.67. WHERE primeiro filtra os funcionários do departamento de Tecnologia, depois a agregação é realizada nos resultados filtrados.


Exemplo: Múltiplas Funções de Agregação + Filtragem Condicional

SQL
-- Estatísticas de valor de pedidos: apenas pedidos concluídos
SELECT COUNT(*) AS qtd_pedidos,
       SUM(total_amount) AS valor_total,
       AVG(total_amount) AS valor_medio_pedido,
       MAX(total_amount) AS maior_pedido,
       MIN(total_amount) AS menor_pedido
FROM orders
WHERE status = 'completed';
▶ Experimente

Saída:

TEXT
qtd_pedidos  valor_total  valor_medio_pedido  maior_pedido  menor_pedido
-----------  -----------  ------------------  -------------  ------------
5            42500.00     8500.00             15000.00       2800.00
💡 Interpretação: WHERE primeiro filtra os pedidos concluídos, depois realiza os cálculos de agregação nesses pedidos. Note que WHERE é executado antes da agregação.


🎬 Cenários de Prática

Cenário 1: Relatório de RH — Visão Geral Salarial do Departamento

O RH precisa de um relatório para entender a situação salarial geral da empresa e quantos funcionários possuem informações de contato.

SQL
SELECT 
    COUNT(*) AS total_funcionarios,
    COUNT(email) + COUNT(phone) AS total_contatos,
    SUM(salary) AS despesa_salarial_anual,
    AVG(salary) AS salario_medio_mensal,
    MAX(salary) - MIN(salary) AS diferenca_salarial
FROM employees
WHERE hire_date >= '2024-01-01';
💡 Abordagem: Use WHERE para filtrar funcionários contratados após 2024, depois use múltiplas funções de agregação para resumir dados de diferentes dimensões.

Cenário 2: Análise de Vendas — Distribuição de Valor dos Pedidos

Analise a distribuição de valor de todos os pedidos enviados.

SQL
SELECT 
    COUNT(*) AS qtd_pedidos_enviados,
    COUNT(DISTINCT customer_id) AS qtd_clientes_unicos,
    SUM(total_amount) AS total_vendas,
    AVG(total_amount) AS valor_medio_pedido,
    MAX(total_amount) AS maior_pedido,
    MIN(total_amount) AS menor_pedido
FROM orders
WHERE status = 'shipped';
💡 Abordagem: COUNT(DISTINCT customer_id) ajuda a entender quantos clientes únicos fizeram pedidos, e não apenas a contagem de pedidos.


❓ Perguntas Frequentes

P: Existe diferença entre COUNT(*) e COUNT(1)? R: Em bancos de dados modernos não há praticamente diferença — o otimizador os trata como o mesmo plano de execução. COUNT(*) é a sintaxe mais padrão e é recomendada.

P: Como o AVG lida com NULL? R: AVG ignora valores NULL. Se 2 de 5 funcionários têm salários NULL, AVG(salary) calcula usando apenas os 3 salários não-NULL, sem dividir por 5. Para tratar NULL como 0, use AVG(COALESCE(salary, 0)).

P: Funções de agregação podem ser aninhadas? R: Não diretamente. Por exemplo, MAX(AVG(salary)) causará um erro. Para encontrar "o departamento com o maior salário médio", use GROUP BY + ORDER BY AVG(salary) DESC LIMIT 1, ou use uma subconsulta.

P: O que SUM retorna para uma tabela vazia? R: SUM, AVG, MAX e MIN retornam NULL para uma tabela vazia ou quando todos os valores são NULL, não 0. COUNT retorna 0. Para retornar 0 em vez disso, use COALESCE(SUM(nome_coluna), 0).


📖 Resumo

Função Finalidade Tratamento de NULL Funciona com DISTINCT
COUNT(*) Contar todas as linhas Contado N/A
COUNT(col) Contar linhas não-NULL Ignorado
SUM(col) Soma Ignorado
AVG(col) Média Ignorado (excluído do denominador)
MAX(col) Máximo Ignorado
MIN(col) Mínimo Ignorado

📝 Exercícios

Exercício 1 (⭐): Consulte a tabela employees para encontrar o total de funcionários, o maior salário, o menor salário e o salário médio.

Exercício 2 (⭐⭐): Consulte a tabela orders para encontrar o número de pedidos concluídos, o valor total e o valor médio para 2025. Requisito: contar apenas pedidos com status = 'completed'.

Exercício 3 (⭐⭐⭐): Consulte a tabela employees para contar funcionários em cada faixa salarial. Regras: salário >= 15000 é "Alto", >= 10000 é "Médio", e o restante é "Júnior". Dica: use CASE WHEN com funções de agregação.


Próxima Lição

👉 14-group-by - Consultas com Agrupamento: Aprenda consultas com GROUP BY, domine estatísticas por categoria, filtragem de grupos com HAVING e mais!

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%