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
ce391168
Banca
CESPE / CEBRASPE
Órgão
SEFAZ PR
Ano
2026
Cargo
AFE ( )
Em certa secretaria de fazenda, as tabelas contribuinte e pagamento armazenam, respectivamente, informações cadastrais e registros de pagamentos realizados pelos contribuintes, da seguinte forma.   Tabela contribuinte (id_contribuinte, nome)   Tabela pagamento (id_pagamento, id_contribuinte, valor, data_pagamento)   A administração tributária deve identificar pagamentos cujos valores estejam abaixo da média individual dos pagamentos de cada contribuinte, visando à detecção de possíveis inconsistências ou tentativas de fraude.   Considerando essa situação hipotética, assinale a opção em que é apresentada a instrução SQL por meio da qual a operação visada pela administração tributária será corretamente realizada.
  1. ASELECT c.nome, p.valor FROM contribuinte c, pagamento p WHERE p.id_contribuinte = c.id_contribuinte AND p.valor < ALL (   SELECT AVG(valor)   FROM pagamento   GROUP BY id_contribuinte)
  2. BSELECT c.nome, p.valor FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte WHERE p.valor < AVG(p.valor)
  3. CSELECT c.nome, p.valor FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte WHERE p.valor < (SELECT AVG(valor) FROM pagamento)
  4. DSELECT c.nome, p.valor FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte WHERE p.valor < ( SELECT AVG(valor) FROM pagamento WHERE pagamento.id_contribuinte = c.id_contribuinte)
  5. ESELECT nome, valor FROM contribuinte WHERE valor < ( SELECT AVG(valor) FROM pagamento WHERE pagamento.id_contribuinte = contribuinte.id_contribuinte)
Revelar gabarito e comentário

GabaritoD — SELECT c.nome, p.valor FROM contribuinte c JOIN pagamento p ON c.id_contribuinte = p.id_contribuinte WHERE p.valor < ( SELECT AVG(valor) FROM pagamento WHERE pagamento.id_contribuinte = c.id_contribuinte)

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 – Subconsulta Correlacionada e Média por Contribuinte

Gabarito: letra D. A consulta correta usa uma subconsulta correlacionada: para cada linha da tabela pagamento, calcula a média dos valores apenas daquele contribuinte (via WHERE pagamento.id_contribuinte = c.id_contribuinte) e compara o valor do pagamento com essa média individual. As demais alternativas erram ao comparar com a média geral, usar ALL incorretamente, ou tentar usar função de agregação diretamente no WHERE.

O problema pede para identificar pagamentos cujo valor esteja abaixo da média individual de cada contribuinte. Isso significa que a média deve ser calculada por contribuinte, não uma média global de todos os pagamentos. A ferramenta certa para isso é uma subconsulta correlacionada: uma subconsulta que referencia a linha externa (o c.id_contribuinte da consulta principal) e, portanto, é reavaliada para cada linha da consulta externa.

Vamos entender o mecanismo. A consulta principal percorre cada par (contribuinte, pagamento) resultante do JOIN. Para cada um desses pares, a subconsulta calcula AVG(valor) apenas dos pagamentos cujo id_contribuinte é igual ao da linha externa. Se o valor do pagamento atual for menor que essa média, a linha é retornada. Isso atende exatamente ao requisito: comparar cada pagamento com a média dos pagamentos daquele mesmo contribuinte.

Um exemplo concreto: se o contribuinte "João" tem pagamentos de R$ 100, R$ 200 e R$ 300, a média individual dele é R$ 200. A consulta retornaria apenas o pagamento de R$ 100, pois é o único abaixo de R$ 200. Já se usássemos a média geral (considerando todos os contribuintes), o resultado seria diferente e incorreto para o objetivo.

A pegadinha central desta questão é confundir a média geral com a média por grupo. As alternativas A, C e E, de formas diferentes, caem nesse erro. A alternativa B tenta usar AVG(p.valor) diretamente no WHERE, o que é inválido em SQL padrão (funções de agregação não podem aparecer no WHERE sem um GROUP BY ou HAVING). A alternativa D é a única que implementa corretamente a subconsulta correlacionada.

Guarde a distinção: para comparar cada linha com uma estatística do próprio grupo a que ela pertence, use subconsulta correlacionada. Para comparar com uma estatística global, use uma subconsulta simples (não correlacionada). É exatamente essa fronteira que separa a alternativa correta das demais.

  1. 1JOIN contribuinte × pagamento
  2. 2Para cada linha externa
  3. 3Calcula AVG do próprio grupo
  4. 4Filtra p.valor < média
LEVEL · soulevel.com.br

Alternativa A — ❌ Incorreta

Esta alternativa usa p.valor < ALL (SELECT AVG(valor) FROM pagamento GROUP BY id_contribuinte). O ALL compara o valor com todos os valores retornados pela subconsulta. Como a subconsulta retorna a média de cada contribuinte (uma lista de médias), a condição p.valor < ALL (...) exige que o valor seja menor que todas as médias da lista. Isso é muito mais restritivo do que o desejado: um pagamento só seria retornado se fosse menor que a média de todos os contribuintes, o que não corresponde a "abaixo da média individual do próprio contribuinte". Além disso, a subconsulta não é correlacionada, então não há vínculo entre o pagamento da linha externa e o grupo de médias.

Alternativa B — ❌ Incorreta

Aqui, WHERE p.valor < AVG(p.valor) tenta usar a função de agregação AVG diretamente na cláusula WHERE. Em SQL padrão, funções de agregação não podem ser usadas na cláusula WHERE — elas só podem aparecer na lista SELECT ou na cláusula HAVING (quando combinadas com GROUP BY). O comando é sintaticamente inválido e não seria executado. Mesmo que fosse, não haveria a correlação com o contribuinte específico.

Alternativa C — ❌ Incorreta

Esta alternativa compara p.valor com (SELECT AVG(valor) FROM pagamento), que é a média geral de todos os pagamentos da tabela. Isso não atende ao requisito, pois a média deve ser calculada por contribuinte. Um pagamento pode estar abaixo da média geral, mas acima da média individual do seu contribuinte (ou vice-versa). A subconsulta não é correlacionada, então não há filtro por id_contribuinte.

Alternativa D — ✅ Correta ⟵ GABARITO

Esta é a implementação correta da subconsulta correlacionada. O JOIN entre contribuinte e pagamento é feito corretamente, e a subconsulta (SELECT AVG(valor) FROM pagamento WHERE pagamento.id_contribuinte = c.id_contribuinte) calcula a média apenas dos pagamentos do contribuinte da linha externa (referenciado por c.id_contribuinte). Para cada linha do resultado do JOIN, a subconsulta é executada com o id_contribuinte daquela linha, retornando a média individual. A condição p.valor < (...) filtra os pagamentos abaixo dessa média. O resultado é exatamente o que a administração tributária deseja.

Alternativa E — ❌ Incorreta

Esta alternativa tem dois problemas. Primeiro, a consulta principal SELECT nome, valor FROM contribuinte não faz JOIN com a tabela pagamento, então a coluna valor não existe na tabela contribuinte — o comando é inválido. Segundo, mesmo que houvesse um JOIN, a subconsulta referencia contribuinte.id_contribuinte, mas a tabela contribuinte não está na subconsulta (a subconsulta só referencia pagamento), o que também geraria erro de sintaxe ou de referência.

A regra de ouro para levar à prova: quando a comparação é com uma estatística do próprio grupo (média por contribuinte, por departamento, por categoria), a subconsulta deve ser correlacionada, referenciando a linha externa. Quando a comparação é com uma estatística global, a subconsulta é simples. E nunca use função de agregação diretamente no WHERE.

Gabarito: letra D

Link permanente: /questoes/ce391168