Imagina que você trabalha como analista numa universidade (a gente tá montando um banco de dados pra universidade, lembra?). Te pediram não só pra mostrar os estudantes e as notas deles, mas também adicionar na tabela uma coluna com a nota máxima do grupo, pra comparar fácil os resultados. Como resolver isso? Claro, usando subqueries no SELECT!
Uma subquery no SELECT permite calcular valores na hora que a query principal roda. Isso é massa porque você pode juntar cálculos agregados, filtros complexos e até outros conjuntos de dados numa só query.
Básico de subqueries no SELECT
Uma subquery no SELECT funciona exatamente como parece: você coloca o resultado de um SELECT dentro de outro. Assim dá pra calcular valores extras pra cada linha do resultado.
Olha um exemplo simples. Suponha que a gente tem uma tabela students com essa estrutura:
| student_id | name | group_id |
|---|---|---|
| 1 | Linda | 101 |
| 2 | Otto | 102 |
| 3 | Anna | 101 |
E a tabela grades:
| grade_id | student_id | grade |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 2 | 3 |
| 4 | 3 | 5 |
| 5 | 3 | 4 |
Exemplo 1: Adicionando a nota máxima do grupo
Missão: mostrar os nomes dos estudantes, as notas deles e a nota máxima do grupo, pra ver o quanto cada um tá distante do melhor resultado do grupo.
Código SQL:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT MAX(grade) -- essa query retorna só um valor
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS max_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
O que tá rolando aqui:
- Pra cada estudante, pegamos o nome e a nota (
s.name,g.grade). SELECT MAX(grade)— é a subquery que retorna a nota máxima dentro do grupo do estudante.- A subquery roda pra cada linha da query principal e usa o
WHERE students.group_id = s.group_idpra filtrar só o grupo certo.
Exemplo 2: Média das notas do grupo
Quer ser ainda mais útil pra galera da análise? Bora mostrar não só a nota máxima, mas também a média das notas do grupo.
Código SQL:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT AVG(grade)
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS avg_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Agora:
- Em vez de
MAX()a gente usaAVG()pra calcular a média das notas do grupo. - Fica uma análise "ao vivo" dos dados.
Limitações e dicas
Subqueries no SELECT são poderosas, mas tem que usar com cuidado:
- Performance. Cada subquery roda pra cada linha da query principal. Isso pode deixar a query lenta se as tabelas forem grandes. Tipo, se tiver 1000 estudantes, a subquery roda 1000 vezes!
- Índices. Pra acelerar essas queries, é importante indexar direito as colunas que aparecem no
WHEREda subquery. - Leitura. Evita fazer subquery demais dentro de subquery. Se ficar muito complicado, pensa em jogar a lógica pro
FROMou criar tabelas temporárias.
Exemplos de uso
Bora ver mais uns casos legais.
Exemplo 3: Quantidade de cursos de cada estudante
Vamos mostrar uma tabela onde pra cada estudante aparece quantos cursos ele tá matriculado. A tabela enrollments liga com os estudantes pelo student_id:
| student_id | course_id |
|---|---|
| 1 | 201 |
| 1 | 202 |
| 2 | 201 |
| 3 | 203 |
Código SQL:
SELECT
s.name AS student_name,
(
SELECT COUNT(*)
FROM enrollments
WHERE enrollments.student_id = s.student_id
) AS course_count
FROM
students s;
Aqui a subquery conta quantos registros tem na tabela enrollments pra cada estudante.
Exemplo 4: Flag de "aluno nota máxima" pra cada estudante
Vamos mostrar se o estudante é "nota máxima". O critério: todas as notas dele têm que ser 5.
Código SQL:
SELECT
s.name AS student_name,
(
SELECT CASE
WHEN MIN(g.grade) = 5 THEN 'Nota máxima'
ELSE 'Não nota máxima'
END
FROM grades g
WHERE g.student_id = s.student_id
) AS status
FROM
students s;
Aqui a gente usa um CASE dentro da subquery pra dar o status "Nota máxima" só pra quem tem todas as notas igual a 5.
Otimizando subqueries no SELECT
Já falamos que performance pode ser um problema. Aqui vão umas dicas pra melhorar isso:
- Use índices. Se as subqueries filtram dados, garante que as colunas usadas tenham índice.
- Cache os resultados. Às vezes vale a pena jogar as subqueries pra uma
VIEWou tabela temporária. - Menos subquery dentro de subquery. Não exagera na aninhadação se dá pra fazer de um jeito mais simples.
Subqueries no SELECT abrem um monte de possibilidades pra calcular e analisar dados. Mesmo podendo pesar, se você otimizar direitinho, o SQL fica muito mais expressivo e flexível. Então, manda ver nos testes e acha o seu jeito de melhorar as queries!
GO TO FULL VERSION