Um SQL JOIN combina linhas de duas ou mais tabelas com base em uma coluna relacionada, e o tipo que você escolhe (INNER, LEFT, RIGHT, FULL ou CROSS) decide quais linhas sobram no resultado. Além disso, neste guia você vai entender cada um deles com exemplos práticos, diagramas visuais e uma cola de decisão para nunca mais confundir os resultados. De fato, o foco é iniciante, mas o material serve de referência rápida até para quem já é pleno ou sênior.

O que é um SQL JOIN?

Um SQL JOIN combina linhas de duas ou mais tabelas com base em uma coluna relacionada. O INNER JOIN traz só as linhas que existem em ambas; o LEFT JOIN mantém todas as da tabela esquerda; o RIGHT JOIN, todas da direita; e o FULL JOIN, de ambas. Portanto, escolher o JOIN certo evita perder ou duplicar dados. Por isso, bancos relacionais guardam a informação em tabelas separadas justamente para reduzir repetição, e o JOIN é a ponte que reconecta esses dados na hora da consulta. Em resumo, todo SQL JOIN parte dessa mesma ideia.

Na prática, imagine duas tabelas simples. A primeira, clientes, guarda quem são seus clientes. A segunda, pedidos, registra cada compra e aponta para o cliente através de uma coluna em comum, geralmente cliente_id. Assim, essa coluna compartilhada é o que chamamos de chave do relacionamento. De fato, é justamente sobre ela que a condição do JOIN vai operar. Vale lembrar que trabalhar com dados relacionais é fundamento de qualquer aplicação séria, algo que também aparece em temas como bancos de dados vetoriais quando o assunto é busca semântica.

Antes de mergulhar nos tipos, veja um diagrama que resume o comportamento de cada JOIN em relação aos conjuntos de linhas das duas tabelas. Além disso, cada retângulo representa uma tabela, e a área destacada mostra o que sobra no resultado.

Os tipos de JOIN visualmente

INNER
LEFT
RIGHT
FULL

Como funciona o INNER JOIN no SQL?

O INNER JOIN é o tipo de SQL JOIN que retorna apenas as linhas que têm correspondência nas duas tabelas ao mesmo tempo. Ou seja, se um cliente não tem pedido, ele fica de fora; e se um pedido aponta para um cliente inexistente, ele também some do resultado. Por isso, é o JOIN mais usado no dia a dia: quando você quer combinar dados que necessariamente se relacionam, como pedidos com seus respectivos clientes.

Veja a seguir um exemplo prático. A condição após o ON define qual coluna liga as tabelas. Nesse caso, ligamos pedidos.cliente_id a clientes.id.

SQL
SELECT c.nome, p.produto, p.valor
FROM clientes c
INNER JOIN pedidos p ON p.cliente_id = c.id;

Repare no uso dos apelidos c e p. De fato, eles deixam a consulta mais curta e evitam ambiguidade quando as duas tabelas têm colunas com o mesmo nome. Além disso, a palavra INNER é opcional: escrever apenas JOIN produz exatamente o mesmo resultado na maioria dos bancos, incluindo PostgreSQL e MySQL. Ainda assim, deixar o INNER explícito ajuda quem lê depois a entender a intenção sem esforço.

Vale reforçar um ponto que confunde iniciantes: o INNER JOIN silenciosamente descarta linhas sem correspondência. Se você espera 100 clientes no relatório e recebe apenas 60, provavelmente 40 deles não tinham pedidos. Nesse cenário, o LEFT JOIN da próxima seção costuma ser a solução.

Publicidade

Como usar LEFT JOIN e RIGHT JOIN no SQL?

O LEFT JOIN é o SQL JOIN que mantém todas as linhas da tabela à esquerda, mesmo sem correspondência na direita. Dessa forma, quando não há par, as colunas da tabela direita vêm preenchidas com NULL. Na prática, esse é justamente o comportamento que você quer para responder perguntas do tipo “quais clientes ainda não fizeram nenhum pedido?”. O termo left join sql é um dos mais buscados por quem estuda o assunto, e a razão é prática: ele é essencial para não perder registros no relatório.

Observe o exemplo abaixo. Como usamos LEFT JOIN, todo cliente aparece, tenha ele pedido ou não.

SQL
SELECT c.nome, p.produto
FROM clientes c
LEFT JOIN pedidos p ON p.cliente_id = c.id;

-- Somente clientes sem nenhum pedido:
SELECT c.nome
FROM clientes c
LEFT JOIN pedidos p ON p.cliente_id = c.id
WHERE p.id IS NULL;

A segunda consulta usa um truque muito comum: filtrar por p.id IS NULL depois do LEFT JOIN devolve exatamente as linhas da esquerda que não encontraram par. Dessa forma, você isola os clientes sem compras sem precisar de subconsultas complicadas.

O RIGHT JOIN é a imagem espelhada: ele mantém todas as linhas da tabela à direita. Na prática, quase ninguém escreve RIGHT JOIN, porque basta inverter a ordem das tabelas e usar LEFT JOIN para obter o mesmo resultado, que é mais fácil de ler. Por isso, as duas consultas a seguir são equivalentes.

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

-- Mesmo resultado, mais legível:
SELECT c.nome, p.produto
FROM pedidos p
LEFT JOIN clientes c ON c.id = p.cliente_id;

Por isso, a nossa recomendação para quem está começando é simples: prefira sempre o LEFT JOIN e ajuste a ordem das tabelas conforme a sua necessidade. Assim você mantém um padrão único no código e reduz a chance de erro. Quem trabalha com versionamento sabe que consistência facilita a vida da equipe, algo que reforçamos também no nosso guia sobre Git para iniciantes.

Quando usar FULL JOIN e CROSS JOIN?

O FULL JOIN é o SQL JOIN que, também chamado de FULL OUTER JOIN, mantém todas as linhas das duas tabelas, com NULL onde não há correspondência. Em outras palavras, ele é a união do LEFT com o RIGHT. Portanto, use-o quando precisar de uma visão completa dos dois lados ao mesmo tempo, como ao reconciliar duas listas e descobrir o que existe em cada uma que falta na outra. Contudo, atenção: o MySQL não suporta FULL JOIN nativamente, enquanto o PostgreSQL suporta sem problemas.

SQL
SELECT c.nome, p.produto
FROM clientes c
FULL JOIN pedidos p ON p.cliente_id = c.id;

Já o CROSS JOIN faz o chamado produto cartesiano: ele combina cada linha da primeira tabela com cada linha da segunda. Por exemplo, se uma tabela tem 10 linhas e a outra tem 5, o resultado terá 50 linhas. Por não ter cláusula ON, ele não filtra nada por relacionamento. Consequentemente, é raro e perigoso quando aparece por engano, mas útil de propósito para gerar combinações, como todos os tamanhos de todas as cores de um produto.

SQL
SELECT t.tamanho, cor.nome
FROM tamanhos t
CROSS JOIN cores cor;

Um detalhe importante: se você esquecer o ON em um JOIN comum, muitos bancos tratam a consulta como um CROSS JOIN acidental. Consequentemente, o resultado explode em tamanho e trava o servidor. Portanto, sempre confira se a condição de junção está presente. Esse cuidado com desempenho lembra as decisões de arquitetura que discutimos em nosso tutorial de RAG com Claude e pgvector, onde a forma de consultar os dados define a velocidade da aplicação.

Publicidade

Como evitar linhas duplicadas no SQL JOIN?

Para evitar linhas duplicadas no SQL JOIN, garanta que a coluna usada na condição seja única na tabela do lado que multiplica os resultados. De fato, a duplicação acontece quando uma linha da tabela A encontra várias linhas na tabela B: cada par vira uma linha nova. Se um cliente tem 3 pedidos, ele aparece 3 vezes no resultado, e isso é o comportamento correto do banco, não um bug. No entanto, o problema surge quando você não esperava essa multiplicação.

Veja os deslizes mais frequentes e como escapar de cada um deles:

  • Somar valores duplicados. Se você faz SUM(p.valor) após um JOIN que multiplicou linhas, o total infla. Nesse caso, agregue antes de juntar, usando uma subconsulta ou uma CTE com GROUP BY.
  • Esquecer a condição ON. Como vimos, isso gera um produto cartesiano gigante. Portanto, sempre revise se cada JOIN tem seu ON correspondente.
  • Confundir INNER com LEFT. Usar INNER quando queria manter todos os registros faz sumir linhas silenciosamente. Consequentemente, o relatório vem com menos dados do que o esperado.
  • Filtrar no WHERE em vez do ON. Colocar uma condição da tabela direita no WHERE de um LEFT JOIN pode anular o efeito do LEFT, transformando-o em INNER sem você perceber.

Quando a duplicação for realmente indesejada, o DISTINCT pode limpar o resultado. Todavia, use-o com cautela: ele mascara o sintoma sem resolver a causa e pode esconder um erro de modelagem. Aqui existe um trade-off claro. De um lado, o DISTINCT é rápido de escrever e resolve na hora; de outro, a subconsulta com GROUP BY é mais verbosa, porém deixa a intenção explícita e evita totais inflados. Consequentemente, preferimos a agregação antecipada sempre que o resultado alimenta um relatório ou uma soma, porque a legibilidade a longo prazo compensa as poucas linhas extras de código. De fato, na maioria das vezes o certo é agregar os dados antes do JOIN. Esse tipo de raciocínio sobre estrutura de dados conversa diretamente com os fundamentos de programação orientada a objetos, onde modelar bem as entidades evita dores de cabeça depois.

Sobre desempenho, uma dúvida clássica é qual JOIN é mais rápido. Na prática, o tipo do JOIN importa menos do que a existência de índices nas colunas de junção. O PostgreSQL é o banco de dados mais usado, por 58,2% dos desenvolvedores, segundo a Stack Overflow Developer Survey 2025, e parte dessa popularidade vem justamente do seu planejador de consultas maduro, que escolhe a melhor estratégia de JOIN automaticamente quando você tem bons índices. Como a própria documentação do PostgreSQL resume, “índices são uma forma comum de melhorar o desempenho de banco de dados”. Portanto, invista em índices antes de se preocupar com qual JOIN usar.

Cola rápida: qual JOIN usar em cada situação

Para escolher o SQL JOIN certo de forma rápida, use a tabela-resumo abaixo. Ela cruza cada tipo de SQL JOIN com o que ele mantém no resultado e a situação típica de uso. Por fim, guarde esta seção como cola de referência.

Tipo de JOIN O que mantém Quando usar
INNER JOIN Só linhas com par nas duas tabelas Combinar dados que sempre se relacionam
LEFT JOIN Todas da esquerda + pares da direita Manter todos os registros de uma tabela
RIGHT JOIN Todas da direita + pares da esquerda Raro; prefira inverter e usar LEFT
FULL JOIN Todas as linhas de ambas as tabelas Reconciliar duas listas (não há no MySQL)
CROSS JOIN Todas as combinações possíveis Gerar combinações de propósito

Na dúvida entre INNER e LEFT, pergunte-se: “preciso manter registros sem correspondência?”. Se sim, LEFT JOIN. Se não, INNER JOIN. Assim, essa única pergunta resolve a maioria das decisões do dia a dia.

Se você quer sair do modo copiar e colar e realmente dominar consultas, um bom livro de referência acelera muito o aprendizado. Recomendamos Introdução à Linguagem SQL, da Novatec, como base sólida: ele cobre SELECT, filtros, agrupamentos e JOINs de forma didática, com exercícios práticos que fixam cada conceito. De fato, vale o investimento antes de encarar bancos maiores em projetos reais.

Capa do livro Introdução à Linguagem SQL
Introdução à Linguagem SQL
★ 4,8 (1.955) · Thomas Nield · Novatec

Conclusão

Portanto, dominar o SQL JOIN é dominar a forma como bancos relacionais reconectam dados espalhados por tabelas. O INNER traz só o que casa nos dois lados; o LEFT preserva a esquerda; o RIGHT preserva a direita; o FULL mostra tudo; e o CROSS gera todas as combinações. Além disso, a maioria dos problemas de duplicação e de dados sumindo se resolve com uma única pergunta sobre quais registros você precisa manter.

Lembre-se do caminho para praticar. Primeiro, monte duas tabelas pequenas com dados de exemplo. Em seguida, rode cada tipo de JOIN e observe o que muda no resultado. Por fim, aplique a cola de decisão em uma consulta real do seu projeto. Dessa forma, com essa rotina o SQL JOIN deixa de ser motivo de confusão e vira ferramenta natural do seu dia a dia. Cada SQL JOIN passa a ter um propósito claro na sua consulta.

Publicidade

Qual a diferença entre INNER JOIN e LEFT JOIN?
O INNER JOIN retorna só as linhas que existem nas duas tabelas ao mesmo tempo. Já o LEFT JOIN mantém todas as linhas da tabela à esquerda, preenchendo com NULL onde não há correspondência na direita. Portanto, use LEFT quando não quiser perder registros.
O que é um JOIN no SQL?
Um JOIN no SQL combina linhas de duas ou mais tabelas com base em uma coluna relacionada, chamada de chave. É assim que você reconecta dados que ficam separados em tabelas diferentes, como clientes e seus pedidos.
Como evitar linhas duplicadas no JOIN?
A duplicação ocorre quando uma linha encontra vários pares na outra tabela. Para evitar, agregue os dados antes de juntar, usando uma subconsulta ou CTE com GROUP BY. O DISTINCT resolve o sintoma, mas o ideal é tratar a causa na modelagem.
Qual JOIN é mais rápido?
Na prática, o tipo do JOIN importa menos do que a existência de índices nas colunas de junção. Com bons índices, o planejador do banco escolhe a estratégia mais eficiente. Portanto, invista em índices antes de se preocupar com o tipo de JOIN.
O que é um CROSS JOIN?
O CROSS JOIN faz o produto cartesiano: combina cada linha da primeira tabela com cada linha da segunda, sem cláusula ON. Se as tabelas têm 10 e 5 linhas, o resultado tem 50. É útil para gerar combinações de propósito, mas perigoso quando aparece por engano.

Este artigo contém links de afiliado. Portanto, se você comprar por eles, podemos receber uma comissão, sem custo extra para você.