Como usar MySQL JOIN para consultar dados de múltiplas tabelas

De dados isolados a relatórios poderosos: O Guia Definitivo de MySQL JOIN.

Por
Emanuel Negromonte
Emanuel Negromonte é Jornalista, Mestre em Tecnologia da Informação e atualmente cursa a segunda graduação em Engenharia de Software. Com 14 anos de experiência escrevendo sobre...
12 min

Bancos de dados relacionais são projetados para evitar redundância, dividindo informações em tabelas separadas. O verdadeiro poder do SQL surge quando você precisa reconectar esses dados. Se você não dominar os JOINs, seus relatórios estarão sempre incompletos ou lentos.

A cláusula MySQL JOIN permite combinar linhas de duas ou mais tabelas com base em uma coluna relacionada. É a operação fundamental para transformar dados isolados (como IDs de usuários e produtos) em informações úteis (como “Quem comprou o quê”).

Resumo executivo (O que você vai aprender):

  • Tipos Essenciais: A diferença prática entre INNER, LEFT, RIGHT e CROSS JOIN.
  • Workarounds: Como simular o FULL OUTER JOIN (que o MySQL não suporta nativamente).
  • Sintaxe Limpa: Como usar a cláusula USING para simplificar suas queries.

Atualização do post: Atualizado para 2026 | Versão Testada: MySQL 8.4 LTS

Preparação do ambiente (Dados de exemplo)

Para praticar, crie um banco de dados de teste com desenvolvedores, projetos e salários. Copie e cole o código abaixo no seu cliente MySQL ou terminal.

SQL
-- 1. Criação do Banco e Tabelas
CREATE DATABASE company_db;
USE company_db;

CREATE TABLE developers (
    dev_id INT PRIMARY KEY,
    dev_name VARCHAR(50),
    role VARCHAR(50),
    office VARCHAR(50),
    manager_id INT
);

CREATE TABLE projects (
    proj_id INT PRIMARY KEY,
    proj_name VARCHAR(50),
    dev_id INT
);

CREATE TABLE salaries (
    dev_id INT PRIMARY KEY,
    salary INT,
    stock_options VARCHAR(3)
);

-- 2. Inserção de Dados (Seed)
INSERT INTO developers VALUES
(1, 'Tom', 'DevOps Engineer', 'San Francisco', 2),
(2, 'Lisa', 'Engineering Lead', 'Austin', NULL),
(3, 'Dave', 'Senior Developer', 'Seattle', 2),
(4, 'Nina', 'Backend Developer', 'New York', 3);

INSERT INTO projects VALUES
(1001, 'API Gateway', 1),
(1002, 'Cloud Migration', 2),
(1003, 'CI/CD Pipeline', 3),
(1004, 'Kubernetes Setup', 1),
(1005, 'Monitoring Dashboard', 2),
(1006, 'Mobile App', 5); -- Note: dev_id 5 não existe na tabela developers

INSERT INTO salaries VALUES
(1, 95000, 'NO'),
(2, 145000, 'YES'),
(3, 120000, 'YES'),
(4, 85000, 'NO');

NOTA TÉCNICA: Adicionamos intencionalmente um projeto (Mobile App) vinculado ao dev_id = 5, que não existe na tabela de desenvolvedores. Isso servirá para testar como cada JOIN lida com dados órfãos.

MySQL INNER JOIN (A interseção)

O INNER JOIN é o padrão da indústria. Ele retorna apenas as linhas onde há uma correspondência em ambas as tabelas. Dados sem par são descartados.

Sintaxe básica:

SQL
SELECT colunas
FROM tabela1
INNER JOIN tabela2 ON tabela1.coluna = tabela2.coluna;

Exemplo Prático:

Liste o nome do desenvolvedor e o projeto em que ele trabalha.

SQL
SELECT p.proj_id, p.proj_name, d.dev_name
FROM projects p
INNER JOIN developers d ON p.dev_id = d.dev_id;

DICA PRO 2026: Se as colunas de ligação tiverem exatamente o mesmo nome (ex: dev_id em ambas), use a cláusula USING para um código mais limpo:

INNER JOIN developers USING(dev_id);

Resultado: O projeto “Mobile App” não aparece porque o ID 5 não tem dono. A desenvolvedora “Nina” não aparece porque não tem projeto.

MySQL LEFT JOIN (Prioridade à esquerda)

O LEFT JOIN retorna todas as linhas da tabela da esquerda (a primeira citada), mesmo que não haja correspondência na tabela da direita. Quando não há match, o MySQL preenche com NULL.

Exemplo Prático:

Encontre todos os desenvolvedores, inclusive aqueles que estão ociosos (sem projetos).

SQL
SELECT d.dev_name, p.proj_name
FROM developers d -- Tabela da Esquerda (Prioridade)
LEFT JOIN projects p ON d.dev_id = p.dev_id;

Resultado:

  • Nina aparece na lista, mas com proj_name como NULL.

CASO DE USO: Use LEFT JOIN para auditorias, como encontrar usuários que se cadastraram mas nunca fizeram uma compra (WHERE pedido_id IS NULL).

MySQL RIGHT JOIN (Prioridade à direita)

Funciona exatamente como o LEFT, mas inverte a prioridade. Retorna tudo da tabela da direita e os matches da esquerda.

Exemplo Prático:

Liste todos os projetos, inclusive os que não têm desenvolvedor atribuído.

SQL
SELECT d.dev_name, p.proj_name
FROM developers d
RIGHT JOIN projects p ON d.dev_id = p.dev_id;

Resultado:

  • O projeto “Mobile App” aparece, com dev_name como NULL.

VEREDITO: Evite usar RIGHT JOIN. Ele torna a leitura da query confusa (da direita para esquerda). Prefira sempre usar LEFT JOIN e inverter a ordem das tabelas no código.

MySQL FULL OUTER JOIN (A união completa)

O MySQL não suporta a sintaxe FULL OUTER JOIN nativamente. Para obter todos os dados de ambas as tabelas (interseção + dados exclusivos da esquerda + dados exclusivos da direita), você deve usar a técnica de UNION.

Workaround (A Solução):

Combine um LEFT JOIN e um RIGHT JOIN com o operador UNION.

SQL
-- Traz tudo da esquerda + matches
SELECT d.dev_name, p.proj_name
FROM developers d
LEFT JOIN projects p ON d.dev_id = p.dev_id

UNION

-- Traz tudo da direita + matches
SELECT d.dev_name, p.proj_name
FROM developers d
RIGHT JOIN projects p ON d.dev_id = p.dev_id;

Isso garante que você veja Nina (sem projeto) e o Mobile App (sem dev) na mesma lista.

MySQL SELF JOIN (Hierarquias)

O SELF JOIN não é um comando diferente, mas uma técnica onde uma tabela se conecta a ela mesma. É crucial para estruturas hierárquicas, como organogramas ou categorias e subcategorias.

Exemplo Prático:

Descubra quem é o gerente de cada desenvolvedor.

SQL
SELECT 
    subordinado.dev_name AS Funcionario, 
    chefe.dev_name AS Gerente
FROM developers subordinado
JOIN developers chefe ON subordinado.manager_id = chefe.dev_id;

Dicas de performance e melhores práticas (2026)

Para manter seu banco de dados rápido e escalável, siga estas regras de ouro:

  1. Indexação é Obrigatória: As colunas usadas no ON ou USING (chaves estrangeiras) devem ser indexadas. Sem isso, o MySQL fará uma varredura completa (Full Table Scan), travando o sistema em tabelas grandes.
  2. Filtre Antes: Use a cláusula WHERE para reduzir o conjunto de dados antes de tentar fazer o join.
  3. Cuidado com o CROSS JOIN: Se você fizer SELECT * FROM tabela1 JOIN tabela2 sem a cláusula ON, o banco gerará um Produto Cartesiano (todas as combinações possíveis). Duas tabelas de 1.000 linhas geram um resultado de 1 milhão de linhas, o que pode derrubar o servidor.
  4. Prefira Sintaxe Explícita:
    • Ruim (Estilo antigo): SELECT * FROM t1, t2 WHERE t1.id = t2.id
    • Bom (ANSI Standard): SELECT * FROM t1 JOIN t2 ON t1.id = t2.id

Conclusão

Dominar os JOINs é o que separa um iniciante de um analista de dados competente. O INNER resolve 80% dos casos, o LEFT ajuda a encontrar falhas e dados faltantes, e o UNION cobre as lacunas do MySQL.

Qual foi a query mais complexa que você já precisou montar para um relatório?

Perguntas Frequentes (FAQ)

Compartilhe este artigo
Sair da versão mobile