Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — CESPE / CEBRASPE 2026

Banco de DadosConsultas e Comandos em SQL
Código
ce391169
Banca
CESPE / CEBRASPE
Órgão
SEFAZ PR
Ano
2026
Cargo
AFE ( )

contribuinte(
id_contribuinte INTEGER PRIMARY KEY,
nome VARCHAR(100));

 

pagamento(
id_pagamento INTEGER PRIMARY KEY,
id_contribuinte INTEGER,
valor DECIMAL(12,2),
FOREIGN KEY (id_contribuinte) REFERENCES contribuinte(id_contribuinte));

 

As tabelas contribuinte e pagamento apresentadas anteriormente fazem parte do banco de dados da secretaria de fazenda de certo ente federativo. A administração tributária deste ente deseja listar os nomes dos contribuintes cujo valor total de pagamentos é superior à média total dos pagamentos de todos os contribuintes.

 

A partir dessa situação hipotética, assinale a opção em que é corretamente apresentada a instrução adequada, de acordo com o padrão SQL/ANSI, para se obter a lista desejada pela administração tributária.

  1. ASELECT c.nome, SUM(p.valor) FROM contribuinte c JOIN pagamento p USING (id_contribuinte) HAVING SUM(p.valor) > ALL (SELECT AVG(valor) FROM pagamento)
  2. BSELECT c.nome, SUM(p.valor) AS total FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte GROUP BY c.nome HAVING SUM(p.valor) > (SELECT AVG(valor) FROM pagamento)
  3. CSELECT c.nome, p.valor FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte HAVING p.valor > AVG(valor)
  4. DSELECT c.nome, SUM(p.valor) AS total FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte WHERE SUM(p.valor) > (SELECT AVG(valor) FROM pagamento) GROUP BY c.nome
  5. ESELECT c.nome, SUM(p.valor) AS total FROM contribuinte c LEFT JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte GROUP BY c.nome WHERE SUM(p.valor) > (SELECT AVG(valor) FROM pagamento)
Revelar gabarito e comentário

GabaritoB — SELECT c.nome, SUM(p.valor) AS total FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte GROUP BY c.nome HAVING SUM(p.valor) > (SELECT AVG(valor) FROM pagamento)

Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.

SQL – Agregação com GROUP BY e HAVING para Comparação com Média

Gabarito: letra B. A consulta correta agrupa os pagamentos por contribuinte, calcula o total de cada um com SUM(p.valor) e filtra os grupos cujo total supera a média geral de pagamentos, usando HAVING com uma subconsulta (SELECT AVG(valor) FROM pagamento). A cláusula HAVING é a única que pode filtrar resultados de funções de agregação, e a subconsulta calcula a média de todos os pagamentos, exatamente como pede o enunciado.

O problema pede uma consulta que compare o total pago por cada contribuinte com a média geral de todos os pagamentos. Para isso, precisamos de duas operações distintas: agregar os valores por contribuinte e comparar o resultado com um valor calculado sobre toda a tabela. A função SUM soma os valores de um grupo, e a função AVG calcula a média. A cláusula GROUP BY define os grupos (no caso, por nome do contribuinte), e a cláusula HAVING filtra esses grupos com base em uma condição que envolve uma função de agregação. A subconsulta (SELECT AVG(valor) FROM pagamento) retorna a média de todos os pagamentos, que é um valor escalar. A comparação SUM(p.valor) > (SELECT AVG(valor) FROM pagamento) é, portanto, válida e atende exatamente ao requisito.

A pegadinha central desta questão está na distinção entre WHERE e HAVING. O WHERE filtra linhas individuais antes do agrupamento, e por isso não pode usar funções de agregação. O HAVING filtra grupos após o agrupamento, e é o único lugar onde SUM, AVG, COUNT etc. podem aparecer na condição de filtro. Além disso, a subconsulta deve ser usada para calcular a média geral, pois não é possível usar AVG(valor) diretamente no HAVING sem uma subconsulta, já que isso se referiria à média de cada grupo, não à média geral. A alternativa correta combina GROUP BY c.nome com HAVING SUM(p.valor) > (SELECT AVG(valor) FROM pagamento), que é a estrutura canônica para esse tipo de comparação.

Vamos analisar cada alternativa em detalhe, identificando o erro específico de cada uma.

  1. 1JOIN contribuinte × pagamento
  2. 2GROUP BY c.nome
  3. 3SUM(p.valor) por grupo
  4. 4HAVING > subconsulta AVG
LEVEL · soulevel.com.br

Alternativa A — ❌ Incorreta

O erro está no uso de HAVING sem GROUP BY. A cláusula HAVING só pode ser usada após um GROUP BY para filtrar grupos. Sem GROUP BY, a consulta trata toda a tabela como um único grupo, e a função SUM(p.valor) agregaria todos os pagamentos, não por contribuinte. Além disso, > ALL (SELECT AVG(valor) FROM pagamento) compara o total com a média de cada pagamento individual, o que não é o que se pede. A sintaxe USING (id_contribuinte) é válida, mas a falta de GROUP BY torna a consulta semanticamente incorreta para o objetivo.

Alternativa B — ✅ Correta ⟵ GABARITO

Esta é a instrução correta. Ela faz o JOIN entre contribuinte e pagamento usando ON c.id_contribuinte = p.id_contribuinte, agrupa os resultados por c.nome com GROUP BY c.nome, calcula o total de pagamentos de cada contribuinte com SUM(p.valor) AS total, e filtra os grupos com HAVING SUM(p.valor) > (SELECT AVG(valor) FROM pagamento). A subconsulta (SELECT AVG(valor) FROM pagamento) retorna a média de todos os pagamentos, e a comparação é feita corretamente. A ordem das cláusulas está correta: SELECT, FROM, JOIN, GROUP BY, HAVING.

Alternativa C — ❌ Incorreta

Esta alternativa tem dois erros graves. Primeiro, não há GROUP BY, então SUM(p.valor) não pode ser usado no SELECT sem agrupar. Segundo, a condição HAVING p.valor > AVG(valor) é inválida: p.valor é uma coluna individual, não uma agregação, e AVG(valor) sem GROUP BY não faz sentido no HAVING. Além disso, a consulta não calcula o total por contribuinte, apenas seleciona valores individuais.

Alternativa D — ❌ Incorreta

O erro está no uso de WHERE SUM(p.valor) > (SELECT AVG(valor) FROM pagamento). A cláusula WHERE não pode conter funções de agregação como SUM, pois ela filtra linhas antes do agrupamento. A condição correta deveria estar no HAVING, após o GROUP BY. A ordem das cláusulas também está errada: WHERE deve vir antes de GROUP BY, não depois.

Alternativa E — ❌ Incorreta

Esta alternativa tem dois erros. Primeiro, a ordem das cláusulas está incorreta: WHERE deve vir antes de GROUP BY, mas aqui aparece depois. Segundo, o uso de WHERE SUM(p.valor) > (SELECT AVG(valor) FROM pagamento) é inválido, pois WHERE não pode usar funções de agregação. A condição deveria estar no HAVING. Além disso, o LEFT JOIN não é necessário para o objetivo, pois a consulta deve listar apenas contribuintes que têm pagamentos (a condição SUM(p.valor) > média já exclui contribuintes sem pagamentos, pois SUM seria NULL).

Gabarito: letra B

Link permanente: /questoes/ce391169