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.

Pratique