Pular para o conteúdo principal

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

Banco de DadosConsultas e Comandos em SQL
Código
fg161114
Banca
FGV
Órgão
Pref RJ
Ano
2023
Cargo
FR ( )

Considere a existência de uma tabela relacional N, com apenas uma coluna, intitulada numero, contendo os números inteiros de 1 até 100, um em cada linha, como ilustrada a seguir.

 

N

numero

1
2
...
99
100
 

Como pode haver discrepâncias entre implementações da linguagem SQL, é dado que a função sqrt(x) retorna a raiz quadrada de x e que a expressão a % b retorna o resto da divisão inteira de a por b.

 

Este é o resultado produzido por um determinado script SQL que utiliza a tabela N, anteriormente descrita.

 
AB
250
333
425
520
616
714
 

Abaixo, são apresentadas três versões para o referido script, não necessariamente corretas.

 

I. select x.numero A,

(select count(*) from N

where N.numero % x.numero = 0) B

from (select numero from N

where numero >= 2 and numero <= 7) x

order by 2 desc

 

II. select x.numero A,

(select count(*) from N

where N.numero % x.numero = 0) B

from (select numero from N

where numero >= 2 and numero <= 7) x

where x.numero % x.numero = 0

order by 2 desc

 

III. select x.numero A,

(select count(*) from N

where N.numero % x.numero = 0) B

from (select numero from N

where numero >= 2 and numero <= 7) x

where x.numero % x.numero = 0

group by x.numero

having count(*) > 0

order by 2 desc

 

Sobre essas afirmativas, é correto afirmar que:

  1. Anenhuma delas produz o resultado correto;
  2. Bsomente I e II produzem o resultado correto;
  3. Csomente II e III produzem o resultado correto;
  4. Dsomente III produz o resultado correto;
  5. Etodas produzem o resultado correto.
Revelar gabarito e comentário

GabaritoE — todas produzem o resultado correto.

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: subconsultas correlacionadas e contagem de divisores

Gabarito: letra E. As três versões produzem o resultado correto porque, embora II e III acrescentem cláusulas aparentemente restritivas, essas cláusulas são sempre verdadeiras para os valores de x.numero (2 a 7), não alterando o conjunto de linhas retornado. A subconsulta correlacionada conta, para cada x.numero, quantos números de 1 a 100 são divisíveis por ele, gerando exatamente a tabela A/B apresentada.

A questão explora o comportamento de subconsultas correlacionadas e o efeito de cláusulas WHERE e GROUP BY/HAVING sobre o resultado. Vamos entender o que cada script faz.

A tabela N contém os inteiros de 1 a 100. A consulta externa seleciona x.numero (valores 2, 3, 4, 5, 6, 7) e, para cada um, executa uma subconsulta correlacionada que conta quantas linhas de N satisfazem N.numero % x.numero = 0, ou seja, quantos números de 1 a 100 são múltiplos de x.numero. O resultado é ordenado pela coluna B (contagem) em ordem decrescente.

Vamos calcular as contagens esperadas:

  • Para x.numero = 2: múltiplos de 2 entre 1 e 100 → 50 (2, 4, ..., 100).

  • Para x.numero = 3: múltiplos de 3 → 33 (3, 6, ..., 99).

  • Para x.numero = 4: múltiplos de 4 → 25 (4, 8, ..., 100).

  • Para x.numero = 5: múltiplos de 5 → 20 (5, 10, ..., 100).

  • Para x.numero = 6: múltiplos de 6 → 16 (6, 12, ..., 96).

  • Para x.numero = 7: múltiplos de 7 → 14 (7, 14, ..., 98).

Esses valores correspondem exatamente à tabela A/B do enunciado, na ordem decrescente de B: (2,50), (3,33), (4,25), (5,20), (6,16), (7,14).

Agora, analisemos as diferenças entre as versões:

  • Versão I: sem cláusula WHERE adicional, apenas a subconsulta correlacionada. Retorna as 6 linhas com as contagens corretas.

  • Versão II: adiciona WHERE x.numero % x.numero = 0. Para qualquer inteiro positivo, x.numero % x.numero é sempre 0, pois todo número é divisível por ele mesmo. Portanto, essa condição é sempre verdadeira para todos os valores de x.numero (2 a 7). Logo, não filtra nenhuma linha, e o resultado é idêntico ao da versão I.

  • Versão III: adiciona GROUP BY x.numero e HAVING count(*) > 0. Como cada valor de x.numero é único na subconsulta externa (2, 3, 4, 5, 6, 7), o agrupamento por x.numero cria um grupo para cada valor, e count(*) dentro do grupo é 1 (uma linha por grupo). A condição HAVING count(*) > 0 é verdadeira para todos os grupos, então nenhum grupo é eliminado. O resultado permanece o mesmo.

Portanto, as três versões produzem exatamente o mesmo resultado, que é o apresentado no enunciado.

A pegadinha está em pensar que as cláusulas adicionais em II e III alterariam o resultado, mas elas são inócuas nesse contexto específico. A banca testa se o candidato percebe que x.numero % x.numero = 0 é sempre verdadeiro e que GROUP BY/HAVING com count(*) > 0 não elimina grupos quando cada grupo tem pelo menos uma linha.

  1. 1Versão I: subconsulta direta
  2. 2Versão II: WHERE sempre verdadeiro
  3. 3Versão III: GROUP BY/HAVING inócuo
  4. 4Resultado idêntico nas três
LEVEL · soulevel.com.br

Alternativa A — ❌ Incorreta

Afirma que nenhuma das versões produz o resultado correto. Isso é falso, pois todas produzem o resultado esperado, como demonstrado.

Alternativa B — ❌ Incorreta

Afirma que somente I e II produzem o resultado correto. A versão III também produz, pois o GROUP BY e o HAVING não alteram o resultado.

Alternativa C — ❌ Incorreta

Afirma que somente II e III produzem o resultado correto. A versão I também produz, pois é a consulta base sem filtros adicionais.

Alternativa D — ❌ Incorreta

Afirma que somente III produz o resultado correto. As versões I e II também produzem.

Alternativa E — ✅ Correta ⟵ GABARITO

Todas as versões produzem o resultado correto. A versão I é a consulta direta; a versão II adiciona uma condição sempre verdadeira; a versão III adiciona agrupamento e HAVING que não eliminam nenhum grupo. Portanto, o resultado é idêntico nas três.

NÃO CAIA NESSA!

A banca tenta fazer o candidato acreditar que as cláusulas extras em II e III alterariam o resultado. A condição x.numero % x.numero = 0 é sempre verdadeira (todo número é divisível por si mesmo), e o GROUP BY/HAVING count(*) > 0 não elimina grupos quando cada grupo tem pelo menos uma linha. Perceba que a pegadinha está em não reconhecer que essas cláusulas são inócuas.

PEGA ESSA DICA!

Em questões de SQL, sempre avalie se as cláusulas adicionais realmente filtram ou agrupam de forma a alterar o resultado. Teste mentalmente com valores concretos: para x.numero = 2, a condição 2 % 2 = 0 é verdadeira; para x.numero = 3, 3 % 3 = 0 também. E o GROUP BY com count(*) > 0 só eliminaria grupos vazios, o que não ocorre aqui.

Gabarito: letra E

Link permanente: /questoes/fg161114