CodeGym /Cursos /SQL SELF /Erros comuns ao usar JOIN

Erros comuns ao usar JOIN

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

Agora chegou a hora de falar da vida real. Daquele lado que ninguém escapa: erros. Pegar, corrigir e entender erros é parte obrigatória de quem mexe com dados. Bora ver quais são as armadilhas mais comuns quando você usa JOIN no SQL e como fugir delas.

Erro 1: Esquecer a condição de junção — criando produto cartesiano

O erro mais comum é esquecer de colocar a condição de junção usando ON. Nesse caso, rola um produto cartesiano, onde cada linha da primeira tabela se junta com cada linha da segunda. O resultado? Um monte de linha sem sentido nenhum, só pra te confundir.

Vamos ver um exemplo. Suponha que temos as seguintes tabelas:

Estudantes (students):

student_id name
1 Otto
2 Anna

Cursos (courses):

course_id course_name
101 Matemática
102 História

Agora vamos escrever uma query esquecendo do ON:

SELECT *
FROM students
JOIN courses;

Resultado:

student_id name course_id course_name
1 Otto 101 Matemática
1 Otto 102 História
2 Anna 101 Matemática
2 Anna 102 História

Parece certo isso? Nem um pouco! Esse pesadelo aí é o tal do produto cartesiano.

Como resolver: usa o ON pra dizer como os dados das tabelas estão ligados.

SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;

E aí já aparece outro tipo de erro...

Proteção contra vacilo

Isso é tão comum que no PostgreSQL é proibido usar JOIN sem ON e sem condição.

Se você realmente quiser juntar cada linha com cada linha, pode usar a sintaxe sem JOIN:

SELECT *
FROM students, courses;

Mais um caso — quando JOIN sem ON funciona:

  • Com NATURAL JOIN — ele junta automaticamente pelas colunas que têm o mesmo nome.
  • Com USING — você diz quais colunas usar pra juntar.
  • CROSS JOIN — sempre sem condição, é o produto cartesiano mesmo.

Erro 2: Condição de junção errada

Às vezes você coloca a condição de junção, mas faz isso errado. Por exemplo, junta tabelas por campos que não têm nada a ver.

Suponha que a gente quer listar estudantes e os cursos em que estão inscritos, mas erra e junta as tabelas por campos que não têm relação:

SELECT *
FROM students
JOIN courses
ON students.student_id = courses.course_id;

Essa query vai dar resultado errado, porque student_id e course_id não têm nada a ver um com o outro.

Como resolver: confere se você está usando as colunas certas pra juntar. O jeito certo seria assim (se você tiver uma tabela enrollments ligando estudantes e cursos):

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Erro 3: Duplicação de linhas no resultado

Quando você coloca vários JOIN na query, às vezes isso gera linhas duplicadas. Isso acontece se nas tabelas do JOIN tem registros repetidos, ou se você colocou a condição de junção errada.

Por exemplo, o estudante Otto está inscrito duas vezes no mesmo curso na tabela enrollments.

Registros em enrollments:

student_id course_id
1 101
1 101

Agora a query com JOIN vai dar esse resultado:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Resultado:

name course_name
Otto Matemática
Otto Matemática

Como resolver: primeiro, confere se não tem dados duplicados nas suas tabelas. Segundo, se isso for esperado, remove os duplicados usando DISTINCT:

SELECT DISTINCT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Erro 4: Perda de linhas usando INNER JOIN

INNER JOIN só retorna as linhas que têm correspondência nas duas tabelas. Se faltar valor em uma delas, a linha é descartada. Você pode perder dados se escolher o tipo de junção errado.

Por exemplo, temos um estudante que ainda não se inscreveu em nenhum curso:

Estudantes (students):

student_id name
1 Otto
2 Anna
3 Dhany

Inscrições (enrollments):

student_id course_id
1 101
2 102

Agora a query com INNER JOIN:

SELECT students.name, courses.course_name
FROM students
JOIN enrollments ON students.student_id = enrollments.student_id
JOIN courses ON enrollments.course_id = courses.course_id;

Resultado:

name course_name
Otto Matemática
Anna História

Cadê o Dhany? Se você quiser incluir estudantes sem cursos, tem que usar LEFT JOIN:

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id;

Erro 5: Tratamento errado de valores NULL

Se em uma das tabelas tem linhas com valores vazios (NULL), elas podem ficar de fora do resultado (por exemplo, quando você usa condições de filtro).

Exemplo: você usa LEFT JOIN, mas depois coloca um WHERE pra filtrar.

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.course_name = 'Matemática';

Agora os estudantes sem curso não vão aparecer no resultado, mesmo usando LEFT JOIN.

Como resolver: se quiser incluir linhas sem curso, troca o WHERE por ON ou adiciona uma condição extra:

SELECT students.name, courses.course_name
FROM students
LEFT JOIN enrollments ON students.student_id = enrollments.student_id
LEFT JOIN courses ON enrollments.course_id = courses.course_id
WHERE courses.course_name IS NULL OR courses.course_name = 'Matemática';

Erro 6: Confusão entre tipos de junção

Você se confunde sobre qual tipo de junção usar. Por exemplo, usa RIGHT JOIN quando dava pra usar LEFT JOIN só trocando a ordem das tabelas.

Como não se enrolar:

  • Prefira LEFT JOIN sempre que puder. É mais intuitivo.
  • Mude a ordem das tabelas pra evitar precisar de RIGHT JOIN.
2
Tarefa
SQL SELF, nível 12, lição 4
Bloqueado
Correção do produto cartesiano
Correção do produto cartesiano
2
Tarefa
SQL SELF, nível 12, lição 4
Bloqueado
Evitando perda de dados com `LEFT JOIN`
Evitando perda de dados com `LEFT JOIN`
1
Pesquisa/teste
Múltiplos JOIN, nível 12, lição 4
Indisponível
Múltiplos JOIN
Múltiplos JOIN
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION