SQL INNER JOIN: combine linhas de duas tabelas

No SQL com INNER JOIN, você obtém apenas as linhas em que a condição de junção encontra correspondência nas duas tabelas. Use-o para combinar dados relacionados, como vincular registros aos seus valores de referência, quando linhas sem correspondência devem ser excluídas do resultado. Como os dois lados precisam satisfazer o predicado de junção, qualquer linha com chave de junção NULL ou sem correspondência é filtrada automaticamente.

Exemplo de SQL INNER JOIN para combinar tabelas relacionadas

Saída:

A saída aparecerá aqui...

Saída:

+-------------+--------------+
| funcionario | departamento |
+-------------+--------------+
| Alma        | Engenharia   |
| Ben         | Engenharia   |
| Cara        | Vendas       |
+-------------+--------------+
3 row(s)

Como este exemplo funciona

  1. departamentos contém três departamentos; funcionarios contém quatro pessoas, cada uma com uma chave estrangeira departamento_id. O departamento_id de Dan é NULL.
  2. INNER JOIN departamentos d ON d.id = f.departamento_id combina cada linha de funcionário com a linha de departamento cujo id é igual ao departamento_id do funcionário. Apenas pares em que os dois lados correspondem são mantidos.
  3. Dan tem departamento_id = NULL. O operador = retorna desconhecido quando qualquer operando é NULL, então Dan nunca corresponde a nenhum departamento e é excluído.
  4. O departamento RH (id 3) não tem funcionários apontando para ele, então também não aparece. O INNER JOIN remove linhas sem correspondência em ambos os lados.

O que é SQL INNER JOIN?

INNER JOIN produz a interseção de duas tabelas com base em um predicado de junção. Em termos lógicos, ele mantém apenas pares de linhas em que a condição do ON é avaliada como verdadeira. A execução física varia por mecanismo e formato dos dados (nested loops, hash join, merge join), mas o resultado sempre contém apenas linhas correspondentes.

INNER JOIN vs LEFT JOIN

INNER JOINLEFT JOIN
Retorna apenas linhas correspondentes nas duas tabelasRetorna todas as linhas da tabela da esquerda, com NULLs onde não há correspondência
Linhas sem correspondência são descartadas silenciosamenteLinhas sem correspondência à esquerda são preservadas com colunas da direita preenchidas com NULL
Use quando correspondências ausentes significam dados inválidosUse quando você precisa ver todos os registros da esquerda, independentemente de correspondência

Regra: escolha INNER JOIN quando cada linha do resultado precisar de dados válidos de ambas as tabelas. Troque para LEFT JOIN quando precisar manter linhas mesmo sem correspondência à direita.

Erros comuns com SQL INNER JOIN

Predicado de junção ausente ou sempre verdadeiro

Omitir a cláusula ON (ou usar uma condição sempre verdadeira) produz um produto cartesiano: cada funcionário é combinado com cada departamento.

-- Errado: produto cartesiano (12 linhas de 4 × 3)
SELECT * FROM funcionarios, departamentos;

-- Certo: predicado de junção explícito
SELECT * FROM funcionarios f
INNER JOIN departamentos d ON d.id = f.departamento_id;

Chaves de junção não únicas causam multiplicação de linhas

INNER JOIN retorna uma linha de saída por par correspondente. Se você juntar com uma tabela em que a chave não é única, uma linha à esquerda pode corresponder a várias linhas à direita e multiplicar seus resultados.

INNER JOIN vs EXISTS

Use INNER JOIN quando você precisa de colunas das duas tabelas na saída. Use EXISTS quando só precisa filtrar linhas com base em se uma linha relacionada existe. EXISTS também evita multiplicação de linhas se a subconsulta puder corresponder a várias linhas, e o planejador de consultas muitas vezes consegue parar após a primeira correspondência.

-- EXISTS: uma linha por funcionário que tem um departamento correspondente
SELECT f.nome FROM funcionarios f
WHERE EXISTS (SELECT 1 FROM departamentos d WHERE d.id = f.departamento_id);

Notas de desempenho

Indexe as colunas usadas no predicado de junção (departamento_id e departamentos.id neste caso). Sem índice, o mecanismo pode varrer a tabela interna muitas vezes. Para tabelas grandes, valide o plano com EXPLAIN QUERY PLAN; procure por “USING INDEX” ou “SEARCH” em vez de “SCAN”.