Juntando Tabelas
O que e JOIN?
JOIN e como voce combina dados de duas ou mais tabelas em uma unica consulta. Quando voce separou os dados em tabelas diferentes (alunos, cursos, matriculas), o JOIN e o que junta tudo de volta para voce ver as informacoes completas.
Dados de exemplo
Vamos usar essas tabelas nos exemplos:
alunos
| id | nome | cidade |
|---|---|---|
| 1 | Ana | Sao Paulo |
| 2 | Bruno | Curitiba |
| 3 | Carla | Recife |
cursos
| id | nome |
|---|---|
| 1 | Python |
| 2 | Banco de Dados |
matriculas
| id | aluno_id | curso_id |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
Note que Carla (id 3) nao tem nenhuma matricula. Isso vai ser importante nos exemplos.
INNER JOIN
Retorna apenas as linhas que tem correspondencia nas duas tabelas. Se nao tem match, a linha nao aparece.
SELECT a.nome, c.nome AS curso
FROM alunos a
INNER JOIN matriculas m ON m.aluno_id = a.id
INNER JOIN cursos c ON c.id = m.curso_id;
| nome | curso |
|---|---|
| Ana | Python |
| Ana | Banco de Dados |
| Bruno | Python |
Carla nao aparece porque ela nao tem matricula. O INNER JOIN so mostra quem tem match.
LEFT JOIN
Retorna todas as linhas da tabela da esquerda, mesmo que nao tenham correspondencia na direita. Onde nao tem match, aparece NULL.
SELECT a.nome, c.nome AS curso
FROM alunos a
LEFT JOIN matriculas m ON m.aluno_id = a.id
LEFT JOIN cursos c ON c.id = m.curso_id;
| nome | curso |
|---|---|
| Ana | Python |
| Ana | Banco de Dados |
| Bruno | Python |
| Carla | NULL |
Agora Carla aparece, mas com NULL no curso porque ela nao tem matricula.
RIGHT JOIN
Retorna todas as linhas da tabela da direita, mesmo sem correspondencia na esquerda. E o inverso do LEFT JOIN.
SELECT a.nome, c.nome AS curso
FROM matriculas m
RIGHT JOIN cursos c ON c.id = m.curso_id
LEFT JOIN alunos a ON a.id = m.aluno_id;
Na pratica, RIGHT JOIN e pouco usado. Voce pode sempre reescrever como LEFT JOIN invertendo a ordem das tabelas.
Resumo dos JOINs
| Tipo | O que retorna |
|---|---|
| INNER JOIN | Apenas linhas com match nas duas tabelas |
| LEFT JOIN | Todas da esquerda + match da direita (NULL se nao tem) |
| RIGHT JOIN | Todas da direita + match da esquerda (NULL se nao tem) |
Exemplo completo
Listar todos os alunos com seus cursos e a data da matricula:
SELECT
a.nome AS aluno,
a.cidade,
c.nome AS curso,
m.data_matricula
FROM alunos a
LEFT JOIN matriculas m ON m.aluno_id = a.id
LEFT JOIN cursos c ON c.id = m.curso_id
ORDER BY a.nome;
| aluno | cidade | curso | data_matricula |
|---|---|---|---|
| Ana | Sao Paulo | Python | 2025-03-01 |
| Ana | Sao Paulo | Banco de Dados | 2025-03-15 |
| Bruno | Curitiba | Python | 2025-03-10 |
| Carla | Recife | NULL | NULL |
JOIN nos ORMs
Prisma (include)
No Prisma, voce nao escreve JOIN. Voce usa include para trazer dados relacionados:
const alunos = await prisma.aluno.findMany({
include: {
matriculas: {
include: {
curso: true
}
}
}
})
// Resultado:
// [
// { nome: 'Ana', matriculas: [{ curso: { nome: 'Python' } }, ...] },
// { nome: 'Bruno', matriculas: [{ curso: { nome: 'Python' } }] },
// { nome: 'Carla', matriculas: [] }
// ]
Drizzle
import { eq } from 'drizzle-orm'
// INNER JOIN
const resultado = await db
.select({
aluno: alunos.nome,
curso: cursos.nome,
})
.from(alunos)
.innerJoin(matriculas, eq(matriculas.alunoId, alunos.id))
.innerJoin(cursos, eq(cursos.id, matriculas.cursoId))
// LEFT JOIN
const todosAlunos = await db
.select({
aluno: alunos.nome,
curso: cursos.nome,
})
.from(alunos)
.leftJoin(matriculas, eq(matriculas.alunoId, alunos.id))
.leftJoin(cursos, eq(cursos.id, matriculas.cursoId))
Lucid (AdonisJS - preload)
No Lucid, voce usa preload para carregar relacionamentos:
// Carrega alunos com matriculas e cursos
const alunos = await Aluno
.query()
.preload('matriculas', (query) => {
query.preload('curso')
})
// Acesso: alunos[0].matriculas[0].curso.nome
Exercicios
- Escreva um INNER JOIN que retorne o nome do aluno e o nome do curso de cada matricula.
- Use LEFT JOIN para listar todos os cursos, incluindo os que nao tem nenhuma matricula.
- Liste os alunos que NAO estao matriculados em nenhum curso (dica: LEFT JOIN + WHERE ... IS NULL).
- Escreva uma consulta que retorne: nome do aluno, cidade, nome do curso, e ordene por cidade.
Referencias
- JOIN - PostgreSQL Docs -- documentacao oficial
- SQL Joins -- W3Schools com diagramas visuais
- Visual Representation of SQL Joins -- artigo classico com diagramas de Venn
Testa o que você leu
5 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.