Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024

Banco de DadosConsultas e Comandos em SQL
Código
fg165268
Banca
FGV
Órgão
STN
Ano
2024
Cargo
AFFC ( )

ATENÇÃO: use a tabela relacional IPCA a seguir para responder à questão.

 

Tabela IPCA

indice

ano

mes

0,56

202312

0,28

202311

0,24

202310

. . .

. . .

. . .

0,2

20037

-0,15

20036

. . .

. . .

. . .

2,25

20031
2,1200212
3,02200211

. . .

. . .

. . .

0,5720011

A instância da tabela contém os valores do índice IPCA para todos os meses dos anos de 2001 até 2023. Os valores pontilhados representam a continuidade mensal da série. Todas as colunas são numéricas, e não aceitam valores nulos.

 

No contexto da tabela IPCA apresentada, assinale o comando SQL que produz, corretamente, para cada ano, o mês com o maior índice, ou meses, pois pode haver empate entre os índices de dois ou mais meses num mesmo ano.

  1. Aselect *      from ipca      where exists             (select mes, ano from ipca x             where x.ano = ipca.ano                  and x.indice > ipca.indice             group by ano)      order by ano, mês
  2. Bselect ano, mes       from ipca       where not exists              (select mes, ano from ipca x                where x.ano = ipca.ano                    and x.indice > ipca.indice)       order by ano, mês
  3. Cselect ano, mes       from ipca       where not exists              (select mes, ano from ipca x               where x.ano >= ipca.ano                   and x.indice < ipca.indice)        order by ano, mês
  4. Dselect ano, mes       from ipca       where exists            (select * from ipca x             where x.ano = ipca.ano                  and x.indice = ipca.indice             group by mes)      order by ano, mês
  5. Eselect ano, mes      from ipca      where exists             (select mes, ano from ipca x              where x.ano = ipca.ano                     or x.indice > ipca.indice)
Revelar gabarito e comentário

GabaritoB — select ano, mes       from ipca       where not exists              (select mes, ano from ipca x                where x.ano = ipca.ano                    and x.indice > ipca.indice)       order by ano, mês

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”.

Subconsultas correlacionadas e a busca pelo máximo por grupo em SQL

Gabarito: letra B. A consulta correta usa uma subconsulta correlacionada com NOT EXISTS para selecionar, para cada ano, os meses cujo índice não é superado por nenhum outro mês do mesmo ano — exatamente a definição de "maior índice" (ou empate no maior). A alternativa B é a única que implementa essa lógica com precisão: para cada linha da tabela externa, a subconsulta verifica se existe outra linha com o mesmo ano e indice maior; se não existe, a linha é o máximo daquele ano.

O problema pede para encontrar, para cada ano, o mês (ou meses, em caso de empate) com o maior valor de indice. A técnica clássica para isso em SQL é a subconsulta correlacionada: para cada linha da consulta externa, a subconsulta interna é avaliada uma vez, usando valores da linha externa (por isso "correlacionada"). A condição x.ano = ipca.ano faz a correlação, restringindo a comparação ao mesmo ano. A condição x.indice > ipca.indice verifica se existe algum mês daquele ano com índice maior. Se NOT EXISTS for usado, selecionamos apenas as linhas para as quais não existe nenhum índice maior no mesmo ano — ou seja, as linhas com o valor máximo (incluindo empates, pois se dois meses têm o mesmo valor máximo, nenhum deles tem um índice maior que o outro).

Vamos entender por que essa é a abordagem correta e por que as outras alternativas falham. A chave está em entender o que cada cláusula EXISTS ou NOT EXISTS faz com a subconsulta correlacionada. EXISTS retorna verdadeiro se a subconsulta retornar pelo menos uma linha; NOT EXISTS retorna verdadeiro se a subconsulta não retornar nenhuma linha. No contexto de encontrar o máximo, queremos linhas para as quais não existe um índice maior no mesmo ano — por isso NOT EXISTS é o operador certo. A alternativa B usa exatamente isso: WHERE NOT EXISTS (SELECT ... WHERE x.ano = ipca.ano AND x.indice > ipca.indice). Para cada linha da tabela externa, a subconsulta procura um mês do mesmo ano com índice maior; se não encontrar, a linha é selecionada. Isso garante que apenas os meses com o maior índice de cada ano apareçam, incluindo empates.

Um exemplo concreto: suponha que no ano de 2023 os índices sejam 0,56 (dezembro), 0,28 (novembro) e 0,24 (outubro). Para a linha de dezembro (índice 0,56), a subconsulta procura um mês de 2023 com índice maior que 0,56 — não existe, então NOT EXISTS é verdadeiro e a linha é selecionada. Para a linha de novembro (0,28), a subconsulta encontra dezembro (0,56 > 0,28), então NOT EXISTS é falso e a linha é descartada. O mesmo vale para outubro. Se houvesse empate, por exemplo, dois meses com 0,56, ambos seriam selecionados, pois nenhum teria um índice maior que o outro.

A pegadinha que a banca explora é a confusão entre EXISTS e NOT EXISTS, e entre as condições de correlação. Muitos candidatos tentam usar EXISTS com uma condição de igualdade ou com GROUP BY, mas isso não resolve o problema do máximo. A alternativa A usa EXISTS com GROUP BY ano, mas a subconsulta não está correlacionada corretamente para encontrar o máximo — ela apenas verifica se existe algum mês com índice maior, o que é verdadeiro para quase todas as linhas, exceto o máximo global. A alternativa C usa NOT EXISTS mas com a condição x.ano >= ipca.ano AND x.indice < ipca.indice, o que não faz sentido para encontrar o máximo — ela selecionaria linhas que não têm nenhum mês do mesmo ano ou de anos posteriores com índice menor, o que não é o que queremos. A alternativa D usa EXISTS com GROUP BY mes, o que não agrupa por ano e não encontra o máximo. A alternativa E usa EXISTS com OR, o que torna a condição muito ampla e seleciona quase todas as linhas.

Guarde a fronteira entre EXISTS e NOT EXISTS e a importância da correlação: é exatamente nela que as alternativas se dividem. A alternativa correta é a que usa NOT EXISTS com a correlação x.ano = ipca.ano e a comparação x.indice > ipca.indice.

  1. 1Correlacionar pelo grupo (x.ano = ipca.ano)
  2. 2Comparar com > (x.indice > ipca.indice)
  3. 3Usar NOT EXISTS (não há maior)
LEVEL · soulevel.com.br

Alternativa A — ❌ Incorreta

Usa EXISTS em vez de NOT EXISTS. A subconsulta verifica se existe algum mês do mesmo ano com índice maior; para quase todas as linhas isso é verdadeiro (exceto para o máximo global), então a consulta retornaria quase todas as linhas, não apenas os máximos por ano. Além disso, o GROUP BY ano na subconsulta não muda o fato de que EXISTS é verdadeiro para a maioria das linhas. O erro específico é usar EXISTS quando deveria ser NOT EXISTS.

Alternativa B — ✅ Correta ⟵ GABARITO

Usa NOT EXISTS com a subconsulta correlacionada correta: para cada linha, verifica se existe outro mês do mesmo ano (x.ano = ipca.ano) com índice maior (x.indice > ipca.indice). Se não existe, a linha é o máximo daquele ano. Isso seleciona exatamente os meses com o maior índice de cada ano, incluindo empates, pois se dois meses têm o mesmo valor máximo, nenhum deles tem um índice maior que o outro. A consulta está correta e atende ao enunciado.

Alternativa C — ❌ Incorreta

Usa NOT EXISTS, mas com condições erradas: x.ano >= ipca.ano AND x.indice < ipca.indice. Isso verifica se não existe um mês de ano maior ou igual com índice menor, o que não tem relação com encontrar o máximo por ano. A condição x.ano >= ipca.ano quebra a correlação por ano (compara com anos posteriores também) e x.indice < ipca.indice é o oposto do que precisamos. O erro é a condição de correlação e comparação incorretas.

Alternativa D — ❌ Incorreta

Usa EXISTS com GROUP BY mes na subconsulta. A subconsulta verifica se existe algum mês com o mesmo ano e mesmo índice, agrupado por mês. Isso não encontra o máximo por ano — apenas verifica se há duplicatas de índice no mesmo ano, o que não é o que o enunciado pede. O erro é usar EXISTS com GROUP BY mes, que não resolve o problema do máximo.

Alternativa E — ❌ Incorreta

Usa EXISTS com a condição x.ano = ipca.ano OR x.indice > ipca.indice. Essa condição é verdadeira para quase todas as linhas (qualquer linha com o mesmo ano ou com índice maior), então a consulta retornaria quase todas as linhas da tabela. O erro é usar OR em vez de AND, o que torna a condição muito ampla e não seleciona apenas os máximos por ano.

NÃO CAIA NESSA!

A banca explora a confusão entre EXISTS e NOT EXISTS. Para encontrar o máximo por grupo, você precisa selecionar as linhas para as quais não existe um valor maior no mesmo grupo — por isso NOT EXISTS é o operador correto. Muitos candidatos usam EXISTS por engano, mas isso seleciona quase todas as linhas, exceto o máximo global. Lembre-se: NOT EXISTS com a correlação certa é a chave.

PEGA ESSA DICA!

Para questões de "máximo por grupo" com subconsultas, monte o raciocínio assim: (1) a subconsulta deve ser correlacionada pela coluna de grupo (no caso, ano); (2) a condição deve comparar o valor da linha externa com o valor da linha interna usando >; (3) use NOT EXISTS para selecionar as linhas que não têm um valor maior. Esse padrão funciona para qualquer tabela e é muito cobrado em provas.

Gabarito: letra B

Link permanente: /questoes/fg165268