Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2023
Banco de Dados›Consultas e Comandos em SQL
Código
fg161117
Banca
FGV
Órgão
CAM DEP
Ano
2023
Cargo
AL ( )
Quando mencionada, considere a tabela relacional intitulada fibo, com duas colunas, cuja instância, não necessariamente nessa ordem, é exibida a seguir.
Tabela fibo
P
N
1
0
2
1
3
1
4
2
5
3
6
5
7
8
8
13
9
21
10
34
A coluna da esquerda enumera as linhas, continuamente, e a coluna da direita armazena os dez primeiros elementos da sequência de Fibonacci, na qual os dois primeiros termos são 0 e 1, por definição, e cada termo subsequente é a soma dos dois termos anteriores.
Suponha que a tabela fibo, apresentada anteriormente, tenha sido danificada, e sua instância corrente seja a que segue.
P
N
1
0
2
1
3
1
6
5
7
8
Para restaurar a tabela, foi produzido o comando SQL a seguir.
insert into fibo
select f2.P + 1, f1.N + f2.N
from fibo f1, fibo f2
where f1.P = f2.P - 1
and f2.P < 10
and not exists
(select * from fibo f3
where f1.N + f2.N = f3.N and f3.P > f2.P)
À luz das características de funcionamento do SQL, o número mínimo de vezes que esse comando deve ser acionado para restaurar a instância original, é
A1.
B2.
C3.
D4.
E5.
Revelar gabarito e comentário▾
GabaritoC — 3.
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”.
Resolução
Gabarito: letra C — a conta chega a 3 execuções — alternativa C.
A ideia por trás
Em SQL, um comando INSERT ... SELECT insere na tabela todas as linhas que o SELECT retorna, mas apenas as que ainda não existem (se houver restrição de unicidade) ou as que passam no filtro. Aqui, o comando é um self-join: ele combina a tabela com ela mesma, pareando cada linha com a seguinte (f1.P = f2.P-1), e tenta inserir uma nova linha com o próximo número da sequência (soma dos dois anteriores). A cláusula NOT EXISTS impede que um valor já presente em uma posição posterior seja inserido novamente.
A sequência de Fibonacci é recursiva: cada termo é a soma dos dois anteriores. Para gerar um termo, os dois anteriores precisam já estar na tabela. O comando só consegue gerar termos cujos dois antecessores estão presentes. Como a tabela danificada tem lacunas (faltam P=4,5,8,9,10), cada execução só consegue preencher os termos imediatamente seguintes aos pares existentes. A cada execução, novos termos são adicionados, o que permite gerar mais termos na próxima execução.
Esta questão testa o entendimento de como um INSERT ... SELECT com self-join e subconsulta correlacionada se comporta em múltiplas execuções: cada execução só insere os termos que podem ser calculados a partir dos dados já presentes, então é preciso simular execução por execução até completar a tabela.
O que a questão dá
tabela fibo original com 10 linhas (P de 1 a 10, N = Fibonacci)
tabela danificada com 5 linhas: (1,0), (2,1), (3,1), (6,5), (7,8)
comando SQL: INSERT INTO fibo SELECT f2.P+1, f1.N+f2.N FROM fibo f1, fibo f2 WHERE f1.P = f2.P-1 AND f2.P < 10 AND NOT EXISTS (SELECT * FROM fibo f3 WHERE f1.N+f2.N = f3.N AND f3.P > f2.P)
O que queremos: o número mínimo de execuções do comando para restaurar a tabela original
Passo 1 — Listar os pares possíveis na primeira execução
O comando funciona pareando cada linha com a seguinte (f1.P = f2.P-1). Na tabela danificada, os pares são (1,2), (2,3) e (6,7). Precisamos ver o que cada par tenta inserir.
Por que esta fórmula: A condição f1.P = f2.P-1 define o par; o INSERT tenta inserir P = f2.P+1 e N = f1.N+f2.N.
NÃO CAIA NESSA!
Esquecer que o par (6,7) também é válido, pois a condição não exige que os P sejam consecutivos a partir de 1.
Passo 2 — Calcular as inserções da primeira execução
Para cada par, calculamos o que seria inserido e verificamos se já existe na tabela (via NOT EXISTS).
Por que esta fórmula: Para o par (f1, f2), a nova linha é (f2.P+1, f1.N+f2.N). O NOT EXISTS impede inserir se o valor N já existir em uma linha com P > f2.P.
insere (4,2) e (8,13); (3,1) já existe
NÃO CAIA NESSA!
Achar que (3,1) seria inserido de novo, mas o NOT EXISTS bloqueia porque N=1 já existe com P=3 > 2.
Passo 3 — Atualizar a tabela após a primeira execução
A tabela agora tem novas linhas, que permitem novos pares na próxima execução.