CodeGym /Cursos /SQL SELF /Impacto do NULL nas funções agregadas: SUM(), COUNT(), AV...

Impacto do NULL nas funções agregadas: SUM(), COUNT(), AVG(), MIN(), MAX()

SQL SELF
Nível 9 , Lição 2
Disponível

Lembrando: funções agregadas são aquelas que trabalham com várias linhas de dados de uma vez e retornam um único resultado. No PostgreSQL, você vai usar bastante essas funções agregadas:

  • SUM() — soma dos dados.
  • AVG() — cálculo da média.
  • MIN() — encontra o valor mínimo.
  • MAX() — encontra o valor máximo.
  • COUNT() — conta as linhas.

Parece simples: você passa uma coluna ou expressão pra função e recebe o resultado. Mas o que acontece se na coluna aparecer um NULL?

Comportamento do NULL nas agregadas: visão rápida

É aqui que a parada fica interessante:

  • SUM() e AVG() ignoram NULL. Se pelo menos um registro tem NULL, ele simplesmente não entra no cálculo. Faz sentido, né? Como a soma vai aumentar se alguém "não veio pra festa"? Ou como calcular a média se falta um valor?
  • MIN() e MAX() também pulam o NULL. Eles acham o mínimo ou máximo só entre os dados que não são NULL. Então, se você procura o funcionário mais novo e alguém esqueceu de preencher a data de nascimento, o NULL não vai ganhar.
  • COUNT(*) conta todas as linhas, até as que têm NULL. Já COUNT(coluna) só conta as linhas onde a coluna tem valor, ou seja, NULL é ignorado.

Bora ver isso na prática com exemplos.

Exemplos de uso das funções agregadas com NULL

Aqui está a tabela students_scores, que guarda as notas dos estudantes num teste:

student_id name score
1 Alyssa 85
2 Bob NULL
3 Charlie 92
4 Dana NULL
5 Elena 74

Agora vamos fazer uns queries e analisar os resultados:

  1. Soma de todas as notas: SUM()
SELECT SUM(score) AS total_score
FROM students_scores;

Resultado:

total_score
251

Como você vê, os valores NULL foram simplesmente ignorados na soma. Pra Alyssa (85), Charlie (92) e Elena (74), a soma deu 251. Bob e Dana ficaram de fora.

  1. Média das notas: AVG()
SELECT AVG(score) AS average_score
FROM students_scores;

Resultado:

average_score
83.67

De novo, NULL foi ignorado e a média foi calculada só pra quem tem nota: (85 + 92 + 74) / 3 = 83.67.

  1. Nota mínima e máxima: MIN() e MAX()
SELECT
    MIN(score) AS min_score, 
    MAX(score) AS max_score 
FROM students_scores;

Resultado:

min_score max_score
74 92

Aqui também é simples: NULL foi ignorado, e o mínimo ficou 74 e o máximo 92.

  1. Contando linhas: COUNT(*) vs COUNT(coluna)
SELECT
    COUNT(*) AS total_rows, 
    COUNT(score) AS non_null_scores 
FROM students_scores;

Resultado:

total_rows non_null_scores
5 3
  • COUNT(*) contou todas as linhas, até as que score é NULL.
  • COUNT(score) contou só as linhas onde a coluna score tem valor.

Casos práticos

Bora ver uns exemplos do mundo real.

Exemplo 1: Contando funcionários com salário informado e não informado

Imagina que temos uma tabela employees com salários.

id name salary
1 Alex Lin 50000
2 Maria Chi NULL
3 Anna Song 60000
4 Otto Art NULL
5 Liam Park 55000

Queremos saber quantos funcionários informaram o salário e quantos não.

SELECT
    COUNT(*) AS total_employees,
    COUNT(salary) AS employees_with_salary,
    COUNT(*) - COUNT(salary) AS employees_without_salary
FROM employees;

Aqui:

  • COUNT(*) retorna o total de funcionários.
  • COUNT(salary) conta quantos informaram o salário.
  • Pra saber quantos não informaram, é só subtrair um do outro.

Resultado

total_employees employees_with_salary employees_without_salary
5 3 2

Exemplo 2: Calculando o preço médio dos produtos com dados faltando

Você é dono de uma loja mágica, e na tabela products tem a coluna price, mas alguns produtos ainda não têm preço definido.

id name price
1 Magic Wand 150
2 Enchanted Cloak NULL
3 Potion Bottle 75
4 Spell Book 200
5 Crystal Ball NULL

Você quer saber o preço médio só dos produtos que têm preço definido.

SELECT AVG(price) AS average_price
FROM products;

Resultado:

average_price
141.6667

Se você quiser colocar um preço padrão pros produtos sem preço (tipo, deixar 0), pode usar a função COALESCE() que a gente vai ver na próxima aula.

Exemplo 3: Encontrando a idade mínima e máxima dos estudantes

Na tabela students tem a idade dos alunos, mas pra alguns a idade é desconhecida (NULL).

id name age
1 Alex Lin 20
2 Maria Chi NULL
3 Anna Song 19
4 Otto Art 22
5 Liam Park NULL

Queremos saber quem é o mais novo e o mais velho.

SELECT
    MIN(age) AS youngest_student,
    MAX(age) AS eldest_student
FROM students;

Resultado:

youngest_student eldest_student
19 22

Esse query retorna a idade mínima e máxima só dos estudantes que têm idade informada. NULL é ignorado de novo.

Peculiaridades e pegadinhas

Quando você trabalha com NULL nas agregadas, é bom lembrar dessas paradas:

  • Na soma SUM() e na média AVG(), NULL não entra no cálculo. Dá pra usar isso pra não somar valores "vazios".
  • Se quiser contar linhas com NULL na coluna, usa COUNT(*).
  • Usando MIN() ou MAX(), NULL não afeta o resultado. Mas se a coluna inteira for só NULL, o resultado também vai ser NULL.

Dicas pra lidar com NULL

  1. Pense no que você quer resolver. É importante saber se você precisa considerar NULL no seu query. Às vezes, como no AVG(), ignorar é o certo. Outras vezes, como ao contar tudo, é bom incluir as linhas com NULL.
  2. Use COALESCE() quando precisar. Se quiser trocar NULL por um valor padrão nos cálculos, a função COALESCE() vai ser sua amiga (mas isso é assunto pra próxima aula).
  3. Não confunda COUNT(*) com COUNT(coluna). Essa é clássica pra quem tá começando. O primeiro conta todas as linhas, o segundo só as linhas com valor não nulo.

Agora você já sabe como o misterioso NULL pode mexer com as agregadas. Esse conhecimento vai te ajudar a evitar surpresas e usar o NULL a seu favor. Na próxima aula, vamos ver a função poderosa COALESCE() pra lidar com NULL de um jeito ainda mais esperto.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION