Profissional analisando gráficos e tabelas de dados em um notebook
JOIN reúne informações relacionadas para responder perguntas que uma única tabela não consegue responder. Crédito da foto.
Compartilhe este conteúdo

JOIN é o recurso do SQL usado para combinar linhas de duas ou mais tabelas relacionadas. Em vez de repetir o nome do cliente em cada pedido, por exemplo, o banco guarda o cliente em uma tabela, os pedidos em outra e utiliza uma chave para conectá-los. A consulta com JOIN reconstrói essas informações quando precisamos exibi-las.

O cenário: clientes e pedidos separados

Imagine uma loja com duas tabelas. A primeira registra cada cliente uma única vez. A segunda registra os pedidos e guarda em cliente_id a identificação do cliente responsável.

clientesValor de exemplo
id1
nomeAna
cidadePetrolina
pedidosValor de exemplo
id101
cliente_id1
total149,90

A ligação acontece entre clientes.id e pedidos.cliente_id. A primeira coluna normalmente é uma chave primária; a segunda, uma chave estrangeira.

INNER JOIN mostra somente correspondências

INNER JOIN retorna apenas os pares de linhas que satisfazem a condição escrita depois de ON. Clientes sem pedidos e pedidos sem cliente correspondente ficam fora do resultado.

SELECT c.nome, p.id AS pedido, p.total
FROM clientes AS c
INNER JOIN pedidos AS p
ON c.id = p.cliente_id;

Os nomes c e p são aliases: apelidos temporários que deixam a consulta menor e evitam ambiguidade. c.nome significa “coluna nome da tabela clientes”. Já p.id AS pedido renomeia a coluna apenas no resultado.

Como ler a consulta: parta de clientes, encontre os pedidos cujo cliente_id seja igual ao id do cliente e mostre nome, número do pedido e total.

LEFT JOIN preserva todas as linhas da esquerda

Quando a pergunta for “quais clientes fizeram pedido e quais ainda não fizeram?”, use LEFT JOIN. Todas as linhas da tabela à esquerda permanecem. Quando não há correspondência na direita, as colunas do pedido recebem NULL.

SELECT c.nome, p.id AS pedido, p.total
FROM clientes AS c
LEFT JOIN pedidos AS p
ON c.id = p.cliente_id
ORDER BY c.nome;

Essa diferença é importante: o INNER responde sobre os registros conectados; o LEFT também revela ausências. Para listar somente clientes sem pedidos, teste uma coluna da tabela direita:

SELECT c.id, c.nome
FROM clientes AS c
LEFT JOIN pedidos AS p
ON c.id = p.cliente_id
WHERE p.id IS NULL;

Filtro no ON ou no WHERE?

Em junções externas, mudar um filtro de lugar pode mudar o significado. Suponha que queremos manter todos os clientes e mostrar apenas os pedidos pagos:

SELECT c.nome, p.id, p.total
FROM clientes AS c
LEFT JOIN pedidos AS p
ON c.id = p.cliente_id
AND p.status = 'PAGO';

O filtro dentro de ON limita quais pedidos podem combinar, mas mantém todos os clientes. Se escrevermos WHERE p.status = 'PAGO', as linhas sem pedido terão status nulo e serão removidas; na prática, perde-se o objetivo de preservar todos os clientes.

RIGHT JOIN e FULL JOIN

RIGHT JOIN preserva todas as linhas da tabela à direita. Ele é o espelho do LEFT. Muitas equipes preferem reorganizar a ordem das tabelas e usar LEFT porque a leitura costuma ficar mais natural, mas ambos são válidos.

SELECT c.nome, p.id AS pedido
FROM clientes AS c
RIGHT JOIN pedidos AS p
ON c.id = p.cliente_id;

FULL JOIN preserva os dois lados: retorna correspondências, clientes sem pedidos e pedidos sem cliente correspondente. Ele é útil em auditorias e comparações entre conjuntos.

SELECT c.id AS cliente_id, c.nome, p.id AS pedido_id
FROM clientes AS c
FULL JOIN pedidos AS p
ON c.id = p.cliente_id;
TipoO que permaneceUso típico
INNER JOINSomente linhas correspondentesPedidos com seus clientes
LEFT JOINTodas da esquerdaClientes com ou sem pedido
RIGHT JOINTodas da direitaPreservar a segunda tabela
FULL JOINTodas dos dois ladosAuditoria de diferenças

Erros comuns ao usar JOIN

1. Esquecer a condição de junção

Combinar tabelas sem uma condição adequada pode produzir um produto cartesiano: cada linha de uma tabela é combinada com todas as linhas da outra. O resultado cresce rapidamente e geralmente não representa a pergunta desejada.

2. Relacionar colunas erradas

As colunas comparadas precisam representar o mesmo fato. Relacionar clientes.id com pedidos.id apenas porque ambas se chamam id está incorreto; o vínculo está em pedidos.cliente_id.

3. Usar SELECT *

Em uma consulta com várias tabelas, * pode trazer colunas repetidas e dados desnecessários. Selecione explicitamente o que será usado.

4. Ignorar duplicações legítimas

Um cliente com três pedidos aparecerá três vezes. Isso não é necessariamente erro: cada linha representa uma combinação cliente–pedido. Antes de aplicar DISTINCT, entenda a cardinalidade e defina se você quer detalhes ou um resumo.

Exemplo completo com total por cliente

Para exibir todos os clientes, a quantidade de pedidos e o valor total comprado, combinamos LEFT JOIN com agregação:

SELECT
c.id,
c.nome,
COUNT(p.id) AS quantidade_pedidos,
COALESCE(SUM(p.total), 0) AS total_comprado
FROM clientes AS c
LEFT JOIN pedidos AS p
ON c.id = p.cliente_id
GROUP BY c.id, c.nome
ORDER BY total_comprado DESC;

COUNT(p.id) conta apenas pedidos existentes. SUM soma os valores e COALESCE troca o resultado nulo por zero para clientes sem compras. Antes desse passo, revise como filtrar e ordenar resultados em SQL.

Desafio prático

Crie as tabelas categorias e produtos. Depois escreva: (1) um INNER JOIN que mostre produto e categoria; (2) um LEFT JOIN que também mostre categorias sem produtos; e (3) uma consulta que conte quantos produtos existem em cada categoria.

Perguntas frequentes

JOIN precisa de chave estrangeira?

O SQL consegue combinar colunas mesmo sem uma restrição de chave estrangeira, mas a chave documenta o relacionamento e ajuda a impedir referências inválidas. Em um projeto bem estruturado, ela normalmente deve existir.

ON e USING são iguais?

USING (coluna) é um atalho quando a coluna de ligação tem o mesmo nome nas duas tabelas. ON é mais geral, explícito e permite condições diferentes.

Qual JOIN devo aprender primeiro?

Comece por INNER e LEFT. Eles resolvem grande parte das consultas iniciais e deixam clara a diferença entre exigir correspondência e preservar linhas sem correspondência.

Referências bibliográficas

Obras reconhecidas utilizadas para fundamentar os conceitos e exemplos deste artigo.

  1. BEAULIEU, Alan. Learning SQL. 3. ed. O’Reilly Media, 2020.
  2. ELMASRI, Ramez; NAVATHE, Shamkant B. Fundamentals of Database Systems. 7. ed. Pearson, 2016.

Documentação técnica: PostgreSQL Global Development Group. Table Expressions — Joined Tables. Acesso em 22 ago. 2026.

Consulte a bibliografia completa do Código em Sala.