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:
- COUNT = Contar quantos recibos existem hoje (contagem)
- SUM = Somar os valores de todos os recibos (soma)
- AVG = Calcular o valor médio por recibo (média)
- MAX = Encontrar o recibo com o maior valor (máximo)
- MIN = Encontrar o recibo com o menor valor (mínimo)
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:
-- 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.
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).
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.
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 |
-- 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;
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:
-- 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
-- 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;
- 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— useHAVINGem 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
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;
Saída:
total_funcionarios tem_email salario_total salario_medio maior_salario menor_salario
------------------ --------- ------------- ------------- ------------- -------------
8 7 112000.00 14000.00 20000.00 9000.00
Exemplo: Agregação Condicional + DISTINCT
-- 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;
Saída:
qtd_dept_tecnologia qtd_salarios_distintos salario_medio_tecnologia
------------------- ---------------------- ------------------------
3 3 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
-- 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';
Saída:
qtd_pedidos valor_total valor_medio_pedido maior_pedido menor_pedido
----------- ----------- ------------------ ------------- ------------
5 42500.00 8500.00 15000.00 2800.00
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.
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';
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.
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';
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:
AVGignora 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, useAVG(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", useGROUP BY+ORDER BY AVG(salary) DESC LIMIT 1, ou use uma subconsulta.
P: O que SUM retorna para uma tabela vazia? R:
SUM,AVG,MAXeMINretornamNULLpara uma tabela vazia ou quando todos os valores são NULL, não 0.COUNTretorna 0. Para retornar 0 em vez disso, useCOALESCE(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 | ✅ |
- Funções de agregação são as "ferramentas estatísticas" do SQL que comprimem múltiplas linhas em um único valor resumido
- Funções de agregação ignoram automaticamente NULL, exceto
COUNT(*) DISTINCTpode desduplicar antes da agregação- Funções de agregação não podem ser usadas em
WHERE— useHAVINGem vez disso (abordado na próxima lição)
📝 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!



