Informática

SQL JOIN: INNER, LEFT, RIGHT, FULL e CROSS com resultados

O JOIN combina linhas de duas tabelas a partir de uma condição. A prova costuma perguntar quantas linhas voltam ou quais valores aparecem como NULL. A maneira mais segura de acertar é desenhar as duas tabelas e simular o resultado. Os exemplos abaixo foram executados em um banco de teste; os dados são fictícios.

As duas tabelas

Tabela unidade:

id nome
1 Protocolo
2 Compras
3 Arquivo
4 Ouvidoria

Tabela servidor (unidade_id é chave estrangeira; cargo entra na última seção):

id nome unidade_id cargo
1 Ana Lima 1 Analista
2 Bruno Souza 1 Tecnico
3 Carla Dias 2 Analista
4 Diego Alves 2 Analista
5 Elisa Rocha 3 Tecnico
6 Fabio Nunes NULL Analista
7 Gabi Matos 2 Tecnico

Repare em dois casos de borda: Fabio não tem unidade (NULL) e a Ouvidoria não tem servidor. São eles que fazem os tipos de JOIN diferirem.

INNER JOIN: só quem tem par

SELECT s.nome, u.nome
FROM servidor s INNER JOIN unidade u ON u.id = s.unidade_id;

Devolve seis linhas: todos os servidores, exceto Fabio. O NULL nunca é igual a coisa alguma, então Fabio não encontra par. A Ouvidoria também some, pois ninguém aponta para ela. Escrever apenas JOIN equivale a INNER JOIN.

LEFT JOIN: tudo da esquerda

SELECT s.nome, u.nome AS unidade
FROM servidor s LEFT JOIN unidade u ON u.id = s.unidade_id;

Devolve sete linhas: os seis pares do caso anterior mais Fabio Nunes com a unidade NULL. A tabela da esquerda é a que vem antes da palavra JOIN (aqui, servidor). Toda linha dela aparece; onde falta par, as colunas da direita vêm NULL.

Invertendo o lado, unidade u LEFT JOIN servidor s ON s.unidade_id = u.id também devolve sete linhas: Protocolo (2), Compras (3), Arquivo (1) e Ouvidoria com servidor NULL.

Achando quem não tem par

Um uso clássico é a “anti-junção”: listar as unidades sem nenhum servidor.

SELECT u.nome
FROM unidade u LEFT JOIN servidor s ON s.unidade_id = u.id
WHERE s.id IS NULL;

Resultado: Ouvidoria. Note o IS NULL sobre uma coluna da tabela da direita que nunca é nula quando há par (a chave primária).

RIGHT JOIN e FULL JOIN

O RIGHT JOIN é o espelho do LEFT: mantém tudo da tabela da direita. servidor s RIGHT JOIN unidade u devolve sete linhas, incluindo a Ouvidoria com servidor NULL, e deixa Fabio de fora. O FULL JOIN mantém os dois lados e devolveu oito linhas: seis pares, Fabio sem unidade e Ouvidoria sem servidor. Nem todo sistema implementa RIGHT e FULL; confira o sistema citado na questão antes de responder.

Tipo Mantém sem par Linhas neste exemplo
INNER ninguém 6
LEFT (servidor à esquerda) servidores 7
RIGHT (unidade à direita) unidades 7
FULL os dois lados 8
CROSS não há condição 28

CROSS JOIN: produto cartesiano

O CROSS JOIN combina cada linha de uma tabela com todas as da outra, sem condição. Com sete servidores e quatro unidades, resultam 7 x 4 = 28 linhas. Escrever FROM servidor s, unidade u sem condição no WHERE produz o mesmo efeito, e é um erro frequente que gera resultados enormes e sem sentido.

A pegadinha: WHERE que anula o LEFT JOIN

Compare duas consultas que buscam técnicos (Bruno, Elisa e Gabi).

-- A: filtro na condição do JOIN
SELECT u.nome, s.nome
FROM unidade u LEFT JOIN servidor s
  ON s.unidade_id = u.id AND s.cargo = 'Tecnico';

A devolve quatro linhas: Protocolo/Bruno, Compras/Gabi, Arquivo/Elisa e Ouvidoria/NULL. Toda unidade é preservada.

-- B: filtro no WHERE
SELECT u.nome, s.nome
FROM unidade u LEFT JOIN servidor s ON s.unidade_id = u.id
WHERE s.cargo = 'Tecnico';

B devolve só três linhas. A Ouvidoria desapareceu: depois do JOIN, sua linha tem s.cargo NULL, e o WHERE descarta quem não for verdadeiro. Na prática, o WHERE sobre a tabela opcional transforma o LEFT JOIN em INNER JOIN. Quando o objetivo é manter todas as linhas da esquerda, o filtro da direita vai na cláusula ON.

Como resolver uma questão de JOIN

  1. Identifique a tabela da esquerda e a da direita.
  2. Marque quais linhas têm par pela condição do ON.
  3. Acrescente as linhas sem par conforme o tipo (LEFT, RIGHT, FULL).
  4. Só então aplique o WHERE, o agrupamento e a ordenação.
  5. Conte as linhas e confira os NULL.

Erros comuns

  • Achar que LEFT JOIN e RIGHT JOIN devolvem o mesmo número de linhas sempre.
  • Esquecer que NULL não casa com NULL na condição de junção.
  • Usar COUNT(*) em LEFT JOIN quando se quer contar filhos: a linha com NULL conta como 1. O correto é COUNT(s.id), como mostra o guia de GROUP BY e HAVING.
  • Confundir UNION (empilha resultados) com JOIN (une colunas).

Fontes e atualização

Não existe norma oficial brasileira sobre a linguagem SQL. O conteúdo segue o padrão da linguagem e a prática dos sistemas gerenciadores; as contagens e os resultados acima vieram da execução das consultas em um banco de teste. Confira no edital o sistema adotado, pois o suporte a RIGHT e FULL JOIN varia.

Próximos passos

Leia também

Para continuar no site

Viu algo errado, desatualizado ou confuso? Relatar erro nesta página