CodeGym /Cursos /SQL SELF /Usando SELECT dentro de SELECT

Usando SELECT dentro de SELECT

SQL SELF
Nível 13 , Lição 1
Disponível

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:

  1. Pra cada estudante, pegamos o nome e a nota (s.name, g.grade).
  2. SELECT MAX(grade) — é a subquery que retorna a nota máxima dentro do grupo do estudante.
  3. A subquery roda pra cada linha da query principal e usa o WHERE students.group_id = s.group_id pra 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 usa AVG() 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:

  1. 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!
  2. Índices. Pra acelerar essas queries, é importante indexar direito as colunas que aparecem no WHERE da subquery.
  3. Leitura. Evita fazer subquery demais dentro de subquery. Se ficar muito complicado, pensa em jogar a lógica pro FROM ou 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:

  1. Use índices. Se as subqueries filtram dados, garante que as colunas usadas tenham índice.
  2. Cache os resultados. Às vezes vale a pena jogar as subqueries pra uma VIEW ou tabela temporária.
  3. 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!

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION