Imagina que você está juntando duas tabelas: students (estudantes) e enrollments (matrículas em cursos). Se na tabela enrollments não tem informação sobre algum estudante, mas você usa, por exemplo, LEFT JOIN, as linhas da tabela students ainda vão aparecer, mas a info de enrollments vai faltar. Nesses casos, ao invés de dados concretos, aparece NULL.
Mais ou menos assim:
Tabela students:
| id | name |
|---|---|
| 1 | Eva |
| 2 | Peter |
| 3 | Anna |
Tabela enrollments:
| student_id | course_name |
|---|---|
| 1 | Matemática |
| 1 | Informática |
| 2 | Física |
Query com LEFT JOIN:
SELECT students.id, students.name, enrollments.course_name
FROM students
LEFT JOIN enrollments ON students.id = enrollments.student_id;
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemática |
| 1 | Eva | Informática |
| 2 | Peter | Física |
| 3 | Anna | NULL |
E aí, olá NULL! Como você pode ver, pra Anna, que não está matriculada em nenhum curso, a info do curso não aparece, e no lugar disso vem NULL.
Como NULL afeta as queries?
NULL não é "zero" nem "string vazia", é ausência de valor. Esse comportamento tem umas consequências interessantes (e às vezes irritantes):
Comparações com NULL:
Se você escrever algo tipo WHERE course_name = NULL, a query não vai retornar linhas com NULL. Por quê? Porque não dá pra comparar valores diretamente com NULL.
Pra checar se tem NULL, tem que usar operadores especiais:
WHERE course_name IS NULL
Operações matemáticas:
Qualquer operação com NULL retorna NULL. Tipo:
SELECT 5 + NULL; -- resultado: NULL
Funções agregadas:
A maioria das funções agregadas, tipo SUM(), AVG(), ignora NULL, mas COUNT(*) conta elas como "linhas existentes".
Como lidar com NULL?
- Substituir
NULLpor valores mais amigáveis usandoCOALESCE()
A função COALESCE() deixa você trocar NULL por outro valor. Por exemplo, se não tem curso, pode mostrar "Sem curso":
SELECT
students.id,
students.name,
COALESCE(enrollments.course_name, 'Sem curso') AS course_name
FROM
students LEFT JOIN enrollments
ON students.id = enrollments.student_id;
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemática |
| 1 | Eva | Informática |
| 2 | Peter | Física |
| 3 | Anna | Sem curso |
Agora ficou bem melhor, né?
- Filtrando valores
NULL
Se você não quiser ver linhas com NULL, pode usar a condição WHERE ... IS NOT NULL. Tipo assim:
SELECT
students.id,
students.name,
enrollments.course_name
FROM
students LEFT JOIN enrollments
ON students.id = enrollments.student_id
WHERE
enrollments.course_name IS NOT NULL;
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemática |
| 1 | Eva | Informática |
| 2 | Peter | Física |
A Anna some do resultado, porque ela não tem matrícula em nenhum curso.
- Contando levando
NULLem conta: exemplo comCOUNT
Como já falei, algumas funções ignoram NULL e outras não. Por exemplo:
Pra contar todas as linhas, incluindo onde tem NULL:
SELECT COUNT(*) FROM students; -- Conta TODAS as linhas (até onde `course_name` = NULL)
Pra contar só as linhas onde não tem NULL:
SELECT COUNT(course_name) FROM enrollments;
- Expressões condicionais com
CASE
Se você não curte COALESCE() ou quer mais flexibilidade, tenta usar CASE. Tipo assim:
SELECT
students.id,
students.name,
CASE
WHEN enrollments.course_name IS NULL THEN 'Sem curso'
ELSE enrollments.course_name
END AS course_name
FROM
students LEFT JOIN enrollments
ON students.id = enrollments.student_id;
O resultado vai ser igual ao do COALESCE(), mas com CASE dá pra criar regras mais complexas.
- Use
INNER JOINse tiver certeza que não vai terNULL
O jeito mais radical de evitar NULL é não deixar eles aparecerem, usando INNER JOIN. Esse tipo de join só retorna linhas que têm correspondência nas duas tabelas:
SELECT
students.id,
students.name,
enrollments.course_name
FROM
students INNER JOIN enrollments
ON students.id = enrollments.student_id;
Sem surpresas — só estudantes que estão matriculados em cursos.
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemática |
| 1 | Eva | Informática |
| 2 | Peter | Física |
Se seus dados precisam mostrar todos os valores, incluindo NULL, INNER JOIN não serve, mas às vezes é só isso que você precisa.
GO TO FULL VERSION