Menu

SQLite INNER JOIN: Unindo Linhas de Várias Tabelas

Entenda como o INNER JOIN funciona no SQLite: o modelo mental, a cláusula ON, junção de três tabelas e o atalho USING.

Esta página tem editores executáveis — edite, execute e veja a saída na hora.

Um JOIN costura duas tabelas

Bancos de dados relacionais separam os dados em várias tabelas de propósito — clientes numa tabela, pedidos em outra, produtos numa terceira. Assim, cada informação fica em um único lugar. Só que, na hora de responder uma pergunta de verdade ("quais clientes pediram o quê?"), você precisa juntar os pedaços de novo. É exatamente para isso que serve um join.

O INNER JOIN é o mais usado no dia a dia. Ele combina linhas de duas tabelas sempre que uma condição bate, e descarta o resto.

Três clientes, três pedidos, mas o Chen não tem nenhum pedido — então ele simplesmente não aparece no resultado. Essa é a essência do inner: só sobrevivem as linhas que casaram.

Modelo mental: casar linhas e depois filtrar

A melhor forma de ler um INNER JOIN é assim: pegue cada linha da primeira tabela, compare com cada linha da segunda tabela e mantenha o par apenas quando a condição do ON for verdadeira. Na prática, é como se fosse um produto cartesiano gigante seguido de um filtro. O SQLite não executa exatamente desse jeito (ele usa índices sempre que pode), mas esse modelo serve direitinho para prever o que vai sair no resultado.

Alguns hábitos que vale a pena adotar aqui:

  • Use aliases nas tabelas (customers AS c) quando for citá-las mais de uma vez. Reduz a poluição visual.
  • Qualifique as colunas (c.name, o.total) quando ambas as tabelas puderem ter aquele nome.
  • A ordem em ON o.customer_id = c.id não importa — c.id = o.customer_id funciona igual.

INNER JOIN vs JOIN no SQLite

No SQLite (e no SQL padrão), usar só JOIN já é a mesma coisa que INNER JOIN. A palavra-chave INNER é opcional.

Os dois estilos geram o mesmo plano de execução e devolvem as mesmas linhas. Escrever INNER JOIN por extenso é um pequeno ganho de legibilidade em código que mistura tipos de join — o intuito fica óbvio quando há um LEFT JOIN poucas linhas depois.

ON ou USING: qual cláusula usar

Quando as colunas do join têm o mesmo nome nas duas tabelas, USING (coluna) fica mais enxuto que ON a.col = b.col:

USING (customer_id) faz duas coisas: casa as linhas onde customer_id é igual e funde a coluna, fazendo com que ela apareça uma única vez no resultado. Use quando os dois lados realmente compartilham o mesmo nome de coluna. Já o ON é a melhor escolha quando os nomes diferem (orders.customer_id = customers.id) ou quando a condição vai além de uma simples igualdade.

Inner join com 3 tabelas no SQLite

Para juntar várias tabelas no SQLite, basta encadear novas cláusulas JOIN ... ON .... Cada nova cláusula conecta o resultado parcial a mais uma tabela.

Leia de cima para baixo: clientes se ligam a pedidos, e pedidos se ligam a itens. Cada linha do resultado representa uma combinação de cliente–pedido–item. Qualquer linha que não tenha correspondência em algum ponto da cadeia é descartada — é a regra do inner join aplicada em cada etapa.

Filtrando com WHERE

O ON define como as linhas se emparelham. Já o WHERE filtra o resultado já emparelhado. No caso específico do inner join, colocar uma condição extra no ON ou no WHERE gera as mesmas linhas — mas a convenção é manter as condições de junção no ON e os filtros de linha no WHERE.

Em português, isso quer dizer "junte clientes e pedidos, e depois fique só com os clientes do Reino Unido cujo pedido passa de 20." Dois papéis, duas cláusulas — seu eu do futuro vai agradecer. (Quando você começar a escrever LEFT JOIN, a diferença entre ON e WHERE deixa de ser só estética, mas isso fica para a próxima página.)

Várias condições no ON

A cláusula ON aceita qualquer expressão booleana, não apenas uma igualdade. Isso é útil quando o relacionamento entre as tabelas envolve mais de uma coluna, ou quando você quer filtrar o lado direito já no momento do join.

O pedido cancelado some porque a segunda condição não bate. Num inner join, você poderia escrever WHERE o.status = 'paid' e teria o mesmo resultado. A versão com ON mantém a lógica do "o que conta como correspondência" pertinho do join.

Armadilhas comuns

Algumas coisas que costumam pegar a galera de surpresa:

  • Esquecer da cláusula ON. FROM a INNER JOIN b sem ON é erro de sintaxe no SQLite. (Já uma vírgula simples — FROM a, b — compila, mas devolve um cross join, e quase nunca é o que você queria.)
  • Duplicatas inesperadas. Se um cliente tem três pedidos, o nome dele aparece três vezes no resultado. Isso é o comportamento correto do join, não um bug. Use GROUP BY para agregar se quiser uma linha por cliente.
  • Linhas faltando. Se um cliente deveria aparecer e não apareceu, é porque a condição do join não bateu — confira se há NULL nas colunas do join, ou parta para o LEFT JOIN.
  • Nomes de colunas ambíguos. SELECT id FROM customers JOIN orders ON ... dá erro porque as duas tabelas têm uma coluna id. Qualifique: c.id ou o.id.

A seguir: LEFT JOIN

O INNER JOIN é ótimo quando "sem correspondência" significa "ignora essa linha". Mas tem hora que você quer listar todos os clientes, inclusive os que não têm pedido nenhum, com NULL no lugar dos dados ausentes. Para isso existe o LEFT JOIN, que é o próximo da fila.

Perguntas frequentes

O que o INNER JOIN faz no SQLite?

O INNER JOIN retorna apenas as linhas que têm correspondência nas duas tabelas, conforme a condição definida no ON. Linhas que não casam de qualquer um dos lados ficam de fora. Vale lembrar: ele é o padrão — JOIN e INNER JOIN significam exatamente a mesma coisa no SQLite.

Qual a diferença entre INNER JOIN e LEFT JOIN no SQLite?

O INNER JOIN mantém só as linhas que casam dos dois lados. Já o LEFT JOIN preserva todas as linhas da tabela da esquerda e preenche com NULL quando não há correspondência à direita. Use INNER JOIN quando a ausência de match significa 'pula essa linha', e LEFT JOIN quando significa 'mostra mesmo assim'.

Dá para fazer INNER JOIN com três tabelas no SQLite?

Dá sim — é só encadear outra cláusula JOIN ... ON .... Cada join conecta o resultado parcial a uma nova tabela. Não existe limite rígido, mas a legibilidade despenca rápido depois de quatro ou cinco tabelas, e nesses casos uma CTE costuma ajudar bastante.

Quando usar USING em vez de ON?

O USING (coluna) é um atalho para quando a coluna usada na junção tem o mesmo nome nas duas tabelas. Fica mais enxuto e ainda colapsa a coluna duplicada em uma só no resultado. Já o ON é o jeito certo sempre que os nomes diferem ou quando você precisa de uma condição mais elaborada.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR