Junções em SQL explicadas, com um exemplo de cada
Uma junção combina linhas de duas tabelas ao comparar uma coluna. O tipo de junção decide o que acontece com as linhas que não encontram par. Todos os exemplos usam o banco de dados da padaria: 8 clientes e 12 pedidos, dos quais dois foram pedidos de balcão, sem cliente.
INNER JOIN: só as correspondências
Mantém uma linha somente quando os dois lados têm correspondência. Clientes sem pedidos e pedidos sem cliente desaparecem.
SELECT c.last_name, o.order_id FROM customers AS c INNER JOIN orders AS o ON o.customer_id = c.customer_id ORDER BY o.order_id;
Resultado: 10 linhas: os pedidos que pertencem a um cliente.
LEFT JOIN: mantém tudo à esquerda
Mantém cada linha da tabela da esquerda. Quando a tabela da direita não tem correspondência, suas colunas ficam NULL. Filtrar por IS NULL encontra as linhas sem correspondência.
SELECT c.last_name, COUNT(o.order_id) AS orders FROM customers AS c LEFT JOIN orders AS o ON o.customer_id = c.customer_id GROUP BY c.customer_id, c.last_name ORDER BY c.customer_id;
Resultado: Todos os 8 clientes; Kim e Meyer mostram 0 pedidos.
RIGHT JOIN: mantém tudo à direita
É a imagem espelhada do LEFT JOIN. A maioria das pessoas troca a ordem das tabelas e usa LEFT JOIN, que é mais natural de ler.
SELECT o.order_id, c.last_name FROM customers AS c RIGHT JOIN orders AS o ON o.customer_id = c.customer_id ORDER BY o.order_id;
Resultado: Todos os 12 pedidos; os pedidos 4 e 11 têm sobrenome NULL (pedidos de balcão).
FULL JOIN: mantém tudo dos dois lados
Mantém as linhas sem correspondência das duas tabelas. É útil para comparar duas listas e ver o que está faltando em cada lado.
SELECT c.last_name, o.order_id FROM customers AS c FULL JOIN orders AS o ON o.customer_id = c.customer_id ORDER BY o.order_id, c.last_name;
Resultado: 14 linhas: 10 correspondências, 2 pedidos de balcão e os clientes Kim e Meyer sem pedido.
CROSS JOIN: todas as combinações
Combina cada linha da primeira tabela com cada linha da segunda. O número de linhas é o produto dos dois. Use de propósito, por exemplo para montar uma grade de datas e categorias.
SELECT COUNT(*) AS combinations FROM customers CROSS JOIN products;
Resultado: 72, que é 8 clientes vezes 9 produtos.
Auto-junção: uma tabela com ela mesma
Dê dois apelidos à mesma tabela para comparar linhas dentro dela, como dois clientes da mesma cidade.
SELECT a.first_name AS first_customer, b.first_name AS second_customer, a.city FROM customers AS a JOIN customers AS b ON a.city = b.city AND a.customer_id < b.customer_id ORDER BY a.city;
Resultado: Os pares Emma e Hugo (Berlin), Ben e Dev (London) e Chloe e Farid (Paris).
Perguntas comuns
- Por que minha junção retorna mais linhas do que eu esperava?
- Normalmente a coluna da junção não é única em um dos lados, então cada linha encontra várias. Confira as chaves e teste a contagem de linhas antes e depois da junção.
- Faz diferença uma condição estar em ON ou em WHERE?
- Em um INNER JOIN não faz diferença. Em um LEFT JOIN, uma condição sobre a tabela da direita no WHERE remove as linhas sem correspondência e transforma o LEFT JOIN em um INNER JOIN. Coloque-a em ON para mantê-las.
- Qual junção equivale ao PROCV?
- Um LEFT JOIN: toda linha da tabela principal é mantida, e a coluna buscada fica NULL onde nada corresponde, como #N/D. Diferente do PROCV, ele retorna todas as correspondências, não só a primeira.