SQL RIGHT JOIN

Na aula LEFT JOIN, a tabela da esquerda ficava inteira. O RIGHT JOIN, a "junção pela direita", é o espelho dele: a tabela que fica inteira é a da direita, a que vem depois da palavra JOIN. Ele não faz nada que o LEFT JOIN não faça (basta trocar as tabelas de lugar), e por isso muita gente nunca o usa. Mas você vai encontrá-lo em consultas de outras pessoas, e há situações em que ele deixa a consulta mais simples de escrever. Nesta aula, a Ana usa os dois e aprende a converter um no outro.

Você vai aprender
  • O que o RIGHT JOIN guarda: todas as linhas da tabela da direita.
  • Os clientes sem pedido e os produtos nunca vendidos, agora com RIGHT JOIN.
  • A forma antiga, que funciona em qualquer banco: trocar a ordem das tabelas e usar LEFT JOIN.
  • Quando o RIGHT JOIN ajuda: pendurar, no fim de uma consulta pronta, uma tabela da qual você quer todas as linhas.
  • Desde quando o SQLite tem RIGHT JOIN (3.39.0) e o que os outros bancos recomendam.
  • As armadilhas, inclusive o erro de digitação que o SQLite aceita calado.

Os exemplos rodam de verdade no seu navegador, no banco da Loja Aurora.


A ideia: a mesma lista, lida do outro lado

Volte à lista de chamada da aula passada: todos os alunos, com a nota ao lado, e espaço em branco para quem faltou. Agora imagine que a professora escreveu a lista ao contrário, com as notas na coluna da esquerda e os nomes na da direita. A lista é a mesma; só mudou o lado em que estão os nomes. No RIGHT JOIN, a "lista de chamada" (a tabela que aparece inteira) fica do lado direito.

clientes pedidos
clientes LEFT JOIN pedidos
pedidos clientes
pedidos RIGHT JOIN clientes

Nos dois desenhos, o círculo pintado é o dos clientes: os dois JOINs guardam todos os clientes. O que mudou foi só o lado em que clientes foi escrito.


1. O primeiro RIGHT JOIN

Todos os clientes, com os seus pedidos, começando a consulta pela tabela de pedidos. Clientes a partir do 26:

SELECT c.id, c.nome, p.id AS pedido
FROM pedidos p
RIGHT JOIN clientes c ON p.cliente_id = c.id
WHERE c.id >= 26
ORDER BY c.id, p.id;
FROM pedidos p
A tabela da esquerda. Desta vez, é ela que pode ficar com buracos (NULL).
RIGHT JOIN clientes c
Right join = "junção pela direita". A tabela da direita, clientes, aparece inteira. Também se escreve RIGHT OUTER JOIN.
ON p.cliente_id = c.id
A regra do par, a mesma de sempre. No ON, a ordem dos dois lados do = não importa.

O resultado é idêntico ao do clientes LEFT JOIN pedidos da aula passada: a Mirela com os 3 pedidos dela, e os clientes 27 a 30 com pedido em NULL. Na loja inteira, também são 94 linhas:

SELECT COUNT(*)
FROM pedidos p
RIGHT JOIN clientes c ON p.cliente_id = c.id;

Com SELECT *, dá para ver bem onde ficam os buracos: as colunas de pedidos vêm primeiro (a tabela do FROM), todas em NULL para o Paulo, e as de clientes depois:

SELECT *
FROM pedidos p
RIGHT JOIN clientes c ON p.cliente_id = c.id
WHERE c.id = 27;

2. Quem não tem par, com RIGHT JOIN

O padrão "quem nunca…" funciona igual, com o teste de NULL agora na tabela da esquerda:

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

Os mesmos quatro clientes sem pedido. E os produtos nunca vendidos:

SELECT pr.id, pr.nome
FROM itens_pedido i
RIGHT JOIN produtos pr ON i.produto_id = pr.id
WHERE i.produto_id IS NULL;

Experimente: esta consulta procura clientes sem pedido, mas usa um JOIN comum e por isso não acha ninguém. Troque o tipo de JOIN para que os clientes (a tabela da direita) apareçam todos, e o filtro encontre os 4 que nunca compraram. Não mude a ordem das tabelas.

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

3. A forma antiga: trocar a ordem e usar LEFT JOIN

Todo RIGHT JOIN pode ser reescrito como LEFT JOIN: basta trocar as duas tabelas de lugar. A regra do ON continua a mesma.

Com RIGHT JOINA mesma coisa com LEFT JOIN
FROM pedidos p
RIGHT JOIN clientes c ON p.cliente_id = c.id
FROM clientes c
LEFT JOIN pedidos p ON p.cliente_id = c.id
FROM itens_pedido i
RIGHT JOIN produtos pr ON i.produto_id = pr.id
FROM produtos pr
LEFT JOIN itens_pedido i ON i.produto_id = pr.id

Confira, com a primeira linha da tabela:

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

O mesmo resultado do RIGHT JOIN da seção 2. Essa troca era a única forma de fazer um "RIGHT JOIN" no SQLite até 2022: o RIGHT JOIN e o FULL JOIN só chegaram na versão 3.39.0, de 25 de junho de 2022. As notas daquela versão dizem, em inglês, "acrescenta o suporte (há muito esperado) a RIGHT e FULL OUTER JOIN". O editor do guia e o terminal da Ana usam uma versão bem mais nova:

SELECT sqlite_version();
$ sqlite3 --version
3.50.4 2025-07-30 19:33:53 4d8adfb30e03f9cf27f800a2c1ba3c48fb4ca1b08b0f5ed59a4d5ecbf45e20a3 (64-bit)

Se você for usar um SQLite mais antigo que a 3.39.0 (em sistemas antigos, ou dentro de programas que trazem o SQLite embutido), o RIGHT JOIN não vai funcionar lá. A troca de ordem funciona em qualquer versão de qualquer banco.


4. Quando o RIGHT JOIN ajuda

O caso em que o RIGHT JOIN brilha é quando você já tem uma consulta montada e quer pendurar no fim uma tabela da qual precisa de todas as linhas. A Ana tem esta consulta, que junta os itens com os pedidos de 2026:

FROM itens_pedido i
JOIN pedidos p ON i.pedido_id = p.id AND p.data >= '2026-01-01'

Agora ela quer saber quantas vezes cada produto de jardinagem foi vendido em 2026, inclusive os que não venderam nada. Em vez de reorganizar a consulta toda, ela pendura produtos no fim com RIGHT JOIN:

SELECT pr.nome AS produto, COUNT(i.pedido_id) AS vendas_2026
FROM itens_pedido i
JOIN pedidos p ON i.pedido_id = p.id AND p.data >= '2026-01-01'
RIGHT JOIN produtos pr ON i.produto_id = pr.id
WHERE pr.categoria_id = 8
GROUP BY pr.id, pr.nome;
FROM itens_pedido i JOIN pedidos p ON … AND p.data >= '2026-01-01'
Primeiro passo: só os itens de pedidos de 2026.
RIGHT JOIN produtos pr ON i.produto_id = pr.id
Segundo passo: o resultado do primeiro (à esquerda) junta-se com todos os produtos (à direita). Produto sem item em 2026 fica com NULL do lado dos itens.
COUNT(i.pedido_id)
Conta só os itens de verdade, então quem não vendeu fica com 0 (a regra do COUNT da aula LEFT JOIN).

Em 2026, o regador e o kit de sementes venderam uma vez cada; os outros três, nenhuma. Com LEFT JOIN, a mesma consulta precisaria começar por produtos, encadear dois LEFT JOIN (itens e pedidos, com a data no ON do segundo) e contar p.id em vez de i.pedido_id. Os dois jeitos estão certos; o RIGHT JOIN, aqui, só poupou trabalho.


Formas diferentes de fazer a mesma coisa

FormaQuando usar
FROM a LEFT JOIN bO padrão. Quase todo mundo lê consultas da esquerda para a direita, com a tabela principal no FROM. Funciona em todos os bancos e em qualquer versão do SQLite.
FROM b RIGHT JOIN aQuando você pendura, no fim de uma consulta pronta, a tabela da qual quer todas as linhas. Exige SQLite 3.39.0 ou mais novo.
Misturar LEFT e RIGHT na mesma consultaEvite: fica difícil saber qual tabela fica inteira. Reescreva tudo como LEFT JOIN.
Nos outros bancos

MySQL, PostgreSQL e SQL Server têm RIGHT JOIN e RIGHT OUTER JOIN, com o mesmo comportamento. A documentação do MySQL diz que o RIGHT JOIN funciona de forma análoga ao LEFT JOIN e recomenda: "para manter o código portável entre bancos de dados, é recomendado usar LEFT JOIN em vez de RIGHT JOIN". Ou seja, a própria documentação aconselha a forma antiga, a troca de ordem.


Quando dá errado

O filtro da tabela da esquerda no WHERE

A mesma armadilha do LEFT JOIN, só que espelhada: agora o lado com buracos é o da esquerda. A Ana quer todos os clientes a partir do 26, com os pedidos de 2026:

SELECT c.id, c.nome, p.id AS pedido
FROM pedidos p
RIGHT JOIN clientes c ON p.cliente_id = c.id
WHERE c.id >= 26
  AND p.data >= '2026-01-01';

O que acontece: só a Mirela. Os clientes 27 a 30 têm p.data em NULL, e o WHERE os jogou fora: o RIGHT JOIN virou, na prática, um INNER JOIN.

Como consertar: o filtro da tabela que pode ficar vazia (aqui, pedidos) vai para o ON: RIGHT JOIN clientes c ON p.cliente_id = c.id AND p.data >= '2026-01-01'.

Testou o IS NULL do lado errado

No RIGHT JOIN, os buracos ficam na tabela da esquerda. WHERE c.id IS NULL (na tabela que fica inteira) nunca é verdadeiro e devolve 0 linhas, sem erro. Como consertar: teste a chave da tabela do FROM: WHERE p.id IS NULL. Se você se pega confundindo os lados, reescreva com LEFT JOIN.

Escreveu errado e o SQLite entendeu um apelido

A Ana digitou RIGTH em vez de RIGHT, e escreveu a coluna do ON sem a tabela:

SELECT COUNT(*)
FROM pedidos RIGTH JOIN clientes ON cliente_id = clientes.id;

O que acontece: nenhum erro, e 90 linhas, não 94. O SQLite leu pedidos RIGTH como "a tabela pedidos com o apelido RIGTH" (lembre: o AS do apelido é opcional), seguido de um JOIN comum. A consulta virou um INNER JOIN, e os clientes sem pedido sumiram.

Se a tabela já tem apelido, o mesmo erro de digitação gera mensagem, porque não cabe um segundo apelido:

SELECT COUNT(*)
FROM pedidos p RIGTH JOIN clientes c ON p.cliente_id = c.id;

A mensagem: near "RIGTH": syntax error. E se a consulta usar o nome da tabela no ON (pedidos.cliente_id) sem apelido, a mensagem é no such column: pedidos.cliente_id, porque a tabela passou a se chamar RIGTH.

Como evitar: dê apelido a toda tabela num JOIN e escreva toda coluna com o apelido na frente. Assim, um erro de digitação no tipo de JOIN vira mensagem, em vez de resultado errado.

Esqueceu a palavra JOIN
SELECT COUNT(*)
FROM pedidos p RIGHT clientes c ON p.cliente_id = c.id;

A mensagem: near "ON": syntax error. Sem a palavra JOIN, o SQLite não reconhece a junção e se perde ao chegar no ON. Como consertar: RIGHT JOIN clientes c.

Esqueceu o ON

Como nos outros JOINs, o SQLite aceita FROM pedidos p RIGHT JOIN clientes c sem condição e devolve todos os pares: 2.700 linhas. No MySQL, no PostgreSQL e no SQL Server, um RIGHT JOIN sem condição dá erro de sintaxe.


Referência rápida

EscritaO que faz
a RIGHT JOIN b ON …Todas as linhas de b; as que não têm par em a vêm com NULL nas colunas de a
RIGHT OUTER JOINO mesmo que RIGHT JOIN
a RIGHT JOIN b = b LEFT JOIN aTrocar a ordem das tabelas converte um no outro (o ON fica igual)
… WHERE a.chave IS NULLSó as linhas de b sem par
SELECT sqlite_version();Mostra a versão do SQLite (o RIGHT JOIN exige 3.39.0 ou mais)
Mensagem ou sintomaQuer dizer
near "RIGTH": syntax errorErro de digitação no tipo de JOIN (com apelido na tabela)
(nenhuma) linhas de menos com RIGTH JOINSem apelido, a palavra errada virou apelido, e o JOIN virou INNER
near "ON": syntax errorFaltou a palavra JOIN depois de RIGHT
(nenhuma) as linhas sem par sumiramFiltro na tabela da esquerda no WHERE

Exercícios

1. Converta para LEFT JOIN

Reescreva FROM pedidos p RIGHT JOIN clientes c ON p.cliente_id = c.id com LEFT JOIN:

FROM LEFT JOIN ON p.cliente_id = c.id

2. A versão

A partir de qual versão o SQLite aceita RIGHT JOIN?

3. Em FROM itens_pedido i RIGHT JOIN produtos pr ON i.produto_id = pr.id, qual tabela aparece inteira?

4. O que a documentação do MySQL recomenda sobre RIGHT JOIN?

5. SELECT COUNT(*) FROM pedidos RIGTH JOIN clientes ON cliente_id = clientes.id; (com o erro de digitação) devolve 90, sem erro. Por quê?

Missão final: todos os funcionários, pela direita

Missão: mostre os 8 funcionários com quantos pedidos cada um atendeu, inclusive os que atenderam 0. A consulta deve continuar começando por FROM pedidos p: use RIGHT JOIN para que funcionarios fique inteira, e conte de forma que quem não atendeu ninguém fique com 0.

SELECT f.nome AS funcionario, COUNT(*) AS pedidos
FROM pedidos p
JOIN funcionarios f ON p.funcionario_id = f.id
GROUP BY f.id, f.nome;
SELECT f.nome AS funcionario, COUNT(p.id) AS pedidos
FROM pedidos p
RIGHT JOIN funcionarios f ON p.funcionario_id = f.id
GROUP BY f.id, f.nome;

É o mesmo resultado da missão final do LEFT JOIN, por outro caminho. E se você quisesse, numa consulta só, todos os clientes e todos os pedidos, sobrando gente dos dois lados? Aí nem o LEFT nem o RIGHT bastam: é o FULL JOIN.


Resumo

  • RIGHT JOIN mostra todas as linhas da tabela da direita (a que vem depois de JOIN); as sem par vêm com NULL nas colunas da esquerda.
  • a RIGHT JOIN b dá o mesmo que b LEFT JOIN a. Trocar a ordem é a forma antiga, que funciona em qualquer banco e versão.
  • O SQLite tem RIGHT JOIN desde a versão 3.39.0 (junho de 2022). O guia usa a 3.50.4.
  • O MySQL recomenda LEFT JOIN no lugar de RIGHT JOIN, por portabilidade. Use o RIGHT quando ele poupar trabalho, como ao pendurar uma tabela no fim de uma consulta pronta.
  • As armadilhas são as do LEFT JOIN, espelhadas: o filtro da tabela da esquerda vai no ON, e o IS NULL testa a chave da esquerda.
  • Dê apelido a toda tabela: assim, um RIGTH digitado errado vira mensagem de erro, e não um apelido.