0Pricing
SQL Academy · Aula

NULLs em agregações e junções

Como NULL se comporta em COUNT, SUM e JOINs.

NULLs em agregações e junções é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 4 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 Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Academy inclui 4 aulas no total.

Valores NULL mudam os cálculos

As funções de agregação e as junções tratam NULL de maneiras especiais. Se você não conhecer as regras, seus totais e contagens podem ficar incorretos sem que isso seja percebido.

Esta lição mostra como COUNT, SUM, AVG, GROUP BY e as junções externas interagem com valores ausentes.

SELECT amount FROM payments;
-- amount
-- -------
--    100
--   NULL   <- missing
--    200

As agregações ignoram valores NULL

A maioria das funções de agregação — SUM, AVG, MIN, MAX — simplesmente ignora valores NULL. Elas agregam apenas as linhas que contêm dados.

Assim, uma quantia NULL não interrompe SUM; ela apenas fica fora do total.

-- Using amounts 100, NULL, 200
SELECT
  SUM(amount) AS total,  -- 300 (NULL skipped)
  MIN(amount) AS lo,     -- 100
  MAX(amount) AS hi      -- 200
FROM payments;

AVG também ignora valores NULL

AVG divide a soma dos valores que não são NULL pela quantidade de valores que não são NULL. Os valores NULL são excluídos de ambos.

Isso é importante: a média de {100, NULL, 200} é 150, não 100 — o NULL não é contado como zero.

-- (100 + 200) / 2 = 150, the NULL row is ignored
SELECT AVG(amount) AS avg_amount FROM payments;

-- If you WANT NULLs counted as 0, COALESCE first:
SELECT AVG(COALESCE(amount, 0)) AS avg_with_zeros FROM payments; -- 100

COUNT(*) versus COUNT(coluna)

Essa distinção confunde muitas pessoas:

  • COUNT(*) conta as linhas, inclusive as que contêm valores NULL.
  • COUNT(column) conta apenas as linhas em que essa coluna não é NULL.
-- 3 rows total, but only 2 have a non-NULL amount
SELECT
  COUNT(*)       AS row_count,    -- 3
  COUNT(amount)  AS has_amount    -- 2
FROM payments;

COUNT(DISTINCT) e NULL

COUNT(DISTINCT col) conta a quantidade de valores distintos que não são NULL. Os valores NULL são totalmente excluídos — nunca aumentam a contagem de distintos.

Tenha isso em mente ao medir "quantos X exclusivos" existem.

-- statuses: 'paid', NULL, 'paid', 'void'
SELECT COUNT(DISTINCT status) AS distinct_statuses
FROM payments;
-- 2  (paid, void) -- NULL not counted

Agregações de conjunto vazio

Quando uma agregação é executada sobre zero linhas, o resultado depende da função:

  • COUNT(...) retorna 0.
  • SUM, AVG, MIN, MAX retornam NULL.

Use COALESCE para transformar uma soma NULL em 0 quando apropriado.

-- No rows match -> SUM is NULL, not 0
SELECT COALESCE(SUM(amount), 0) AS total
FROM payments
WHERE status = 'refunded';  -- no such rows

GROUP BY agrupa valores NULL

Embora NULL = NULL seja desconhecido em outros contextos, GROUP BY coloca todos os valores NULL em um único grupo.

Assim, uma categoria NULL se torna seu próprio grupo nos resultados, permitindo resumir em conjunto as linhas com dados ausentes.

SELECT category, COUNT(*) AS n
FROM products
GROUP BY category;

-- category | n
-- ---------+---
-- books    | 5
-- toys     | 3
-- NULL     | 2   <- all NULL categories in one group

Valores NULL de junções externas

As junções externas são uma fonte importante de valores NULL. Um LEFT JOIN mantém todas as linhas da esquerda; quando não há correspondência à direita, as colunas do lado direito se tornam NULL.

Esses valores NULL significam "nenhuma linha correspondente", não "um valor NULL armazenado".

SELECT c.name, o.id AS order_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;

-- name  | order_id
-- ------+---------
-- Alice | 10
-- Bob   | NULL     <- Bob has no orders

Contando correspondências após um LEFT JOIN

Para contar apenas correspondências reais após um LEFT JOIN, conte uma coluna que não seja NULL da tabela à direita, não COUNT(*).

COUNT(o.id) ignora as linhas NULL produzidas pelas linhas da esquerda sem correspondência, fornecendo a quantidade real de pedidos.

SELECT c.name, COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;

-- Bob shows 0, not 1×NULL

Filtrando as não correspondências

Uma armadilha sutil: colocar uma condição na tabela à direita em WHERE após um LEFT JOIN transforma-o em uma junção interna, porque NULL = value é desconhecido e acaba sendo filtrado.

Se quiser manter as linhas sem correspondência, coloque a condição na cláusula ON ou verifique explicitamente se há NULL.

-- Accidentally drops Bob (his o.status is NULL)
SELECT c.name FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'open';

-- Keep unmatched rows: move the test into ON
SELECT c.name FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id AND o.status = 'open';

Regras práticas

Leve estas regras para todas as consultas que combinam agregações e junções:

  • As agregações ignoram valores NULL (exceto COUNT(*)).
  • COUNT(col) < COUNT(*) quando a coluna contém valores NULL.
  • SUM/AVG de um conjunto vazio resultam em NULL — envolva-os em COALESCE.
  • LEFT JOIN produz valores NULL para não correspondências; conte uma chave do lado direito.
  • Os filtros da tabela à direita pertencem a ON, não a WHERE.
SELECT c.name,
  COALESCE(SUM(o.amount), 0) AS spent,
  COUNT(o.id)                AS orders
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;

Verificação rápida

Uma coluna amount tem os valores 100, NULL e 200 em três linhas. O que COUNT(*) e COUNT(amount) retornam?

Recapitulação

Você aprendeu como os valores NULL fluem pela agregação e pelas junções: as agregações ignoram valores NULL, COUNT(*) conta linhas enquanto COUNT(col) conta valores que não são NULL, somas de conjuntos vazios são NULL e GROUP BY reúne valores NULL em um único grupo.

Você também viu que as junções externas geram valores NULL para não correspondências e por que os filtros da tabela à direita pertencem a ON. Isso conclui o curso Trabalhando com valores NULL — agora você consegue lidar com dados ausentes com confiança.

-- A NULL-safe summary query
SELECT c.name,
  COUNT(o.id)                AS orders,
  COALESCE(SUM(o.amount), 0) AS total_spent
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name
ORDER BY total_spent DESC;

Perguntas Frequentes

A aula “NULLs em agregações e junções” é grátis?

Sim — o texto completo de “NULLs em agregações e junções” é 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 Academy, atualize para CoddyKit PRO. O curso de SQL Academy inclui 4 aulas no total.

O que vou aprender em “NULLs em agregações e junções”?

Como NULL se comporta em COUNT, SUM e JOINs. Você pratica SQL Academy 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 Academy?

Nenhuma experiência prévia é necessária. SQL Academy 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 4 de 4.

Quanto tempo leva a aula “NULLs em agregações e junções”?

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 Academy?

Sim. Cada aula de SQL Academy 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. O que NULL realmente significa
  2. IS NULL e IS NOT NULL
  3. COALESCE e NULLIF
  4. NULLs em agregações e junções
← Voltar para SQL Academy