Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2023
Banco de Dados›Consultas 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.
A
B
2
50
3
33
4
25
5
20
6
16
7
14
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:
Anenhuma delas produz o resultado correto;
Bsomente I e II produzem o resultado correto;
Csomente II e III produzem o resultado correto;
Dsomente III produz o resultado correto;
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.
1Versão I: subconsulta direta
2Versão II: WHERE sempre verdadeiro
3Versão III: GROUP BY/HAVING inócuo
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.