CodeGym /Cursos /SQL SELF /Trabalhando com valores NULL ao juntar dado...

Trabalhando com valores NULL ao juntar dados

SQL SELF
Nível 12 , Lição 0
Disponível

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?

  1. Substituir NULL por valores mais amigáveis usando COALESCE()

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

  1. 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.

  1. Contando levando NULL em conta: exemplo com COUNT

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;
  1. 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.

  1. Use INNER JOIN se tiver certeza que não vai ter NULL

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.

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