CodeGym /Cursos /SQL SELF /Erros comuns ao trabalhar com subqueries

Erros comuns ao trabalhar com subqueries

SQL SELF
Nível 14 , Lição 4
Disponível

Mexer com subqueries é tipo jogar xadrez apostando a roupa: parece fácil no começo, até você dar um passo em falso. E de onde vêm os erros? Falta de atenção na sintaxe, ignorar as manhas da lógica do SQL ou só distração mesmo. Nessa aula, vamos falar dos erros mais comuns e como fugir deles.

Erros de sintaxe

Subqueries exigem atenção total na sintaxe. Esquecer uma vírgula, parêntese ou alias pode derrubar sua query inteira. Bora ver alguns problemas clássicos.

Parênteses faltando

Parênteses são essenciais quando você usa subqueries. A subquery tem que ficar entre parênteses, e se faltar um só, já dá erro de sintaxe.

Exemplo de erro:

SELECT student_name
FROM students
WHERE student_id IN SELECT student_id FROM enrollments);

Erro:

ERROR:  syntax error at or near "SELECT"

Correção:

SELECT student_name
FROM students
WHERE student_id IN (SELECT student_id FROM enrollments);

Comentário: A query dentro do IN sempre tem que estar entre parênteses, senão o SQL não entende que você quer rodar uma subquery.

Faltando alias

Quando você usa subqueries na seção FROM, não esquece de dar um alias pra ela. Sem isso, o PostgreSQL fica perdido.

Exemplo de erro:

SELECT student_name, avg_score
FROM (SELECT student_id, AVG(score) AS avg_score FROM grades GROUP BY student_id)
WHERE avg_score > 80;

Erro:

ERROR:  subquery in FROM must have an alias

Correção:

SELECT student_name, avg_score
FROM (SELECT student_id, AVG(score) AS avg_score FROM grades GROUP BY student_id) AS subquery
WHERE avg_score > 80;

Comentário: O PostgreSQL exige que toda tabela temporária (resultado da subquery no FROM) tenha um nome.

Problemas de performance

Subqueries, principalmente as mal otimizadas, podem transformar seu banco de dados num trator lento. A performance sofre geralmente por conta de cálculos desnecessários ou falta de índices.

Cálculos desnecessários

Subqueries na seção SELECT podem ser executadas pra cada linha do resultado, o que gasta um tempão.

Exemplo:

SELECT student_name,
       (SELECT COUNT(*) FROM enrollments WHERE enrollments.student_id = students.student_id) AS course_count
FROM students;

Se a tabela students tiver dezenas de milhares de linhas, essa subquery vai rodar de novo pra cada linha.

Otimização:

WITH course_counts AS (
    SELECT student_id, COUNT(*) AS course_count
    FROM enrollments
    GROUP BY student_id
)
SELECT s.student_name, c.course_count
FROM students s
LEFT JOIN course_counts c ON s.student_id = c.student_id;

CTE (Common Table Expression) ou joins evitam recalcular pra cada linha. Vamos falar disso mais pra frente :P

Falta de índices

Se você usa subqueries pesadas na seção WHERE, garante que as colunas certas estão indexadas.

Exemplo:

SELECT student_name
FROM students
WHERE student_id IN (SELECT student_id FROM enrollments WHERE course_id = 10);

Se a coluna student_id na tabela enrollments não tiver índice, a subquery vai fazer um scan completo na tabela.

Otimização: Crie um índice:

CREATE INDEX idx_enrollments_course_id ON enrollments (course_id);

Você já ouviu tanto falar de índices que deve estar curioso pra saber o que é. Mas segura aí, vamos ver isso em outro nível. Índices são importantes, mas servem pra acelerar queries sem mudar o código delas. Eles não transformam uma query ruim em boa, só ajudam a rodar mais rápido no production. Principalmente se as tabelas tiverem milhões de linhas.

Erros de lógica

Erros de lógica em subqueries aparecem tanto quanto os de sintaxe. Os problemas podem vir de não entender direito como funciona o NULL, filtros ou funções agregadas.

Uso errado do NULL

NULL é uma armadilha esperando qualquer iniciante. Quando você usa IN ou NOT IN em subqueries, ter NULL pode mudar o resultado.

Exemplo de erro:

SELECT student_name
FROM students
WHERE student_id NOT IN (SELECT student_id FROM enrollments);

Se na tabela enrollments tiver linhas com student_id = NULL, a query não retorna nada. Isso acontece porque a condição NOT IN vira tipo NULL IS NOT IN.

Correção:

SELECT student_name
FROM students
WHERE student_id NOT IN (SELECT student_id FROM enrollments WHERE student_id IS NOT NULL);

Sempre filtra o NULL quando usar NOT IN.

Erros nas condições de filtro

Muitas vezes a subquery serve pra filtrar de forma mais complexa, mas errar na condição pode fazer o resultado sair totalmente diferente do esperado.

Exemplo de erro:

SELECT student_name
FROM students
WHERE (SELECT AVG(score) FROM grades WHERE grades.student_id = students.student_id) > 80;

Se pelo menos um estudante não tiver notas, a subquery retorna NULL e esse estudante não aparece no resultado.

Correção:

SELECT student_name
FROM students
WHERE COALESCE((SELECT AVG(score) FROM grades WHERE grades.student_id = students.student_id), 0) > 80;

Use COALESCE pra trocar NULL por um valor padrão.

Dicas pra evitar erros

Pra não cair nos erros clássicos com subqueries, segue essas dicas:

Use parênteses e alias direito. Se algo não funcionar, confere se todos os parênteses estão fechados e se as subqueries têm alias.

Otimize suas queries. Tenta evitar subqueries quando dá pra usar JOIN, WITH ou índices.

Fique ligado no NULL. Sempre pensa que pode aparecer NULL nas subqueries e usa IS NOT NULL, COALESCE ou algo parecido.

Teste tudo. Testa cada subquery separada pra garantir que ela retorna o que você espera.

Deixe o código legível. Usa identação e alias pra deixar seu código fácil de ler. Lembra: daqui um mês, nem você vai lembrar o que escreveu.

1
Pesquisa/teste
Uso de subqueries, nível 14, lição 4
Indisponível
Uso de subqueries
Uso de subqueries
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION