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
-- 200As 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; -- 100COUNT(*) 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 countedAgregações de conjunto vazio
Quando uma agregação é executada sobre zero linhas, o resultado depende da função:
COUNT(...)retorna0.SUM,AVG,MIN,MAXretornamNULL.
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 rowsGROUP 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 groupValores 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 ordersContando 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×NULLFiltrando 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/AVGde um conjunto vazio resultam em NULL — envolva-os emCOALESCE.- 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 aWHERE.
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
- O que NULL realmente significa
- IS NULL e IS NOT NULL
- COALESCE e NULLIF
- NULLs em agregações e junções