Questão nº 59
Questão de Análise de Dados · FGV TCU 2021 (nº 59)
ATENÇÃO!
Nas próximas três questões, considere as tabelas de banco de dados T, TX e DUAL, exibidas com suas respectivas instâncias a seguir.
Supondo que a coluna sequencia da tabela T, anteriormente definida, deveria conter números inteiros em sequência contínua, seria preciso descobrir os intervalos de valores faltantes. Um valor é considerado faltante quando a) é um número inteiro n entre o menor e o maior valor da tabela, tal que n não esteja presente na tabela, ou b) é um número presente na tabela T, com valor nulo na coluna caracteristica.
[IMG-PENDENTE]{Q59}
O comando SQL que produz o resultado acima, a partir da instância inicialmente definida para a tabela T, é:
- A```
select t1.sequencia 'inicio', t2.sequencia 'fim',
t2.sequencia - t1.sequencia -1 faltantes
from T t1, T t2
where t1.sequencia < t2.sequencia
and t1.sequencia <> t2.sequencia -1
and not exists
(select * from T t3
where t3.sequencia > t1.sequencia
and t3.sequencia < t2.sequencia)
``` - B```
select t1.sequencia +1 'inicio', t2.sequencia -1 'fim',
t2.sequencia - t1.sequencia -1 faltantes
from T t1, T t2
where t1.sequencia < t2.sequencia
and t1.sequencia <> t2.sequencia -1
and t1.caracteristica is not null
and t2.caracteristica is not null
and (not exists
(select * from T t3
where t3.sequencia > t1.sequencia
and t3.sequencia < t2.sequencia
and t3.caracteristica is not null))
``` (alternativa correta) - C```
select t1.sequencia +1 'inicio', t2.sequencia -1 'fim',
t2.sequencia - t1.sequencia -1 faltantes
from T t1, T t2
where t1.sequencia <> t2.sequencia -1
and t1.caracteristica is not null
and t2.caracteristica is not null
and (not exists
(select from T t3
where t3.sequencia > t1.sequencia
and t3.sequencia < t2.sequencia
and t3.caracteristica is not null)
or exists
(select from T t3
where t3.sequencia > t1.sequencia
and t3.sequencia < t2.sequencia
and t3.caracteristica is null))
``` - D```
select t1.sequencia +1 'inicio', t2.sequencia -1 'fim',
t2.sequencia - t1.sequencia -1 faltantes
from T t1, T t2
where t1.sequencia < t2.sequencia
and t1.sequencia <> t2.sequencia -1
and t1.caracteristica is not null
and t2.caracteristica is not null
and exists
(select * from T t3
where t3.sequencia > t1.sequencia
and t3.sequencia < t2.sequencia)
``` - E```
select t1.sequencia +1 'inicio', t2.sequencia -1 'fim',
t2.sequencia - t1.sequencia -1 faltantes
from T t1, T t2
where t1.sequencia < t2.sequencia
and t1.sequencia <> t2.sequencia -1
and t1.caracteristica is not null
and t2.caracteristica is not null
and not exists
(select * from T t3
where t3.sequencia > t1.sequencia
and t3.sequencia < t2.sequencia)
```
Resposta comentada
Gabarito Alternativa B
Para encontrar intervalos de valores faltantes em uma sequência, precisamos identificar os números que não estão presentes ou que estão presentes, mas com uma característica nula. Um número é considerado não faltante (ou "válido") se ele existe na tabela T e sua coluna caracteristica não é nula. Os comandos SQL geralmente encontram esses intervalos identificando pares de números "válidos" consecutivos e calculando a lacuna entre eles.
- Tabela T:
sequencia | caracteristica ----------|--------------- 1 | 'a' 2 | 'b' 4 | 'c' 5 | NULL 7 | 'd' 8 | 'e' 10 | 'f' - Números "não faltantes" (válidos): Aqueles com
caracteristica IS NOT NULL.
São eles:1, 2, 4, 7, 8, 10. - Gaps (intervalos de faltantes) entre os "não faltantes":
- Entre
2e4: O número3está faltando. - Entre
4e7: Os números5e6estão faltando. (5está emTmas comcaracteristicanula, e6não está emT). - Entre
8e10: O número9está faltando.
- Entre
O resultado esperado, portanto, seria:
inicio | fim | faltantes
-------|-----|----------
3 | 3 | 1
5 | 6 | 2
9 | 9 | 1
Análise das alternativas:
- (A) Incorreta: A cláusula
SELECTestá errada, poisinicioefimdevem sert1.sequencia + 1et2.sequencia - 1, respectivamente, para representar o intervalo entret1et2. Além disso, não exige quet1.caracteristicaet2.caracteristicasejamNOT NULL, e a subconsultaNOT EXISTSnão filtra port3.caracteristica IS NOT NULL, o que faria com que números como5(comcaracteristicanula) fossem considerados "presentes" e quebrassem o intervalo de faltantes. - (B) Correta: Esta alternativa implementa a lógica correta.
select t1.sequencia +1 'inicio', t2.sequencia -1 'fim', t2.sequencia - t1.sequencia -1 faltantes: Calcula corretamente o início, fim e a contagem dos números faltantes no intervalo.t1.sequencia < t2.sequenciaet1.sequencia <> t2.sequencia -1: Garantem quet1vem antes det2e que há pelo menos um número entre eles.t1.caracteristica is not null and t2.caracteristica is not null: Crucial, pois define quet1et2devem ser números "não faltantes" (válidos) para servirem como limites do intervalo.and (not exists (select * from T t3 where t3.sequencia > t1.sequencia and t3.sequencia < t2.sequencia and t3.caracteristica is not null)): Esta é a "pegadinha" e o ponto chave. Esta subconsultaNOT EXISTSverifica se não existe nenhum outro número "não faltante" (válido) entret1.sequenciaet2.sequencia. Se não houver, significa quet1et2são os números "não faltantes" consecutivos, e todo o intervalo entre eles é de números faltantes. Por exemplo, para(t1=4, t2=7), o número5existe emTmas temcaracteristica IS NULL, então ele não satisfazt3.caracteristica IS NOT NULL. O número6não existe emT. Assim, a subconsulta retorna vazio,NOT EXISTSé verdadeiro, e o intervalo5-6é identificado.
- (C) Incorreta: Falta a condição
t1.sequencia < t2.sequencianoWHEREprincipal, o que levaria a resultados incorretos. A condiçãoOR exists (select ... and t3.caracteristica is null)na cláusulaWHEREé problemática, pois combinaria múltiplos intervalos de faltantes em um só se houvesse qualquert3comcaracteristica IS NULLno meio, mesmo que houvesse números "não faltantes" entret1et2. - (D) Incorreta: A condição
exists (select * from T t3 where t3.sequencia > t1.sequencia and t3.sequencia < t2.sequencia)é o oposto do que se busca. Ela exigiria que existisse algum número emTentret1et2(independentemente da característica), o que filtraria os verdadeiros intervalos de faltantes. - (E) Incorreta: A subconsulta
NOT EXISTS(select * from T t3 where t3.sequencia > t1.sequencia and t3.sequencia < t2.sequencia) não inclui a condiçãoand t3.caracteristica is not null. Isso significa que ela consideraria qualquer número presente emT(mesmo comcaracteristicanula, como o5) como um número que "quebra" o intervalo de faltantes. Assim, para o par(t1=4, t2=7), a subconsulta encontrariat3=5, e a condiçãoNOT EXISTSseria falsa, impedindo a identificação do intervalo5-6.
Fonte: FGV TCU 2021 Auditor Federal de Controle Externo - Área Controle Externo (AUFC-CE) (Caderno Tipo 1). Reproduzida para fins de estudo.
