Pular para o conteúdo principal

Questão de Banco de Dados — SQL — FGV 2023

Banco de DadosSQL
Código
fg063595
Banca
FGV
Órgão
DPE-RS
Ano
2023
Nível
Superior
Cargo
Analista - Área de Apoio Especializado - Tecnologia da Informação - Banco de Dados

Tabela R1


Na questão a seguir, considere a tabela R1, cuja instância é exibida a seguir. 

Imagem da questão

Com referência à tabela R1, como descrita anteriormente, analise o comando SQL a seguir.delete from R1 where (select count(*) from R1 x where R1.B = x.B) > 0 Após a execução desse comando, o conjunto completo de linhas presentes na instância da tabela R1 é:
  1. A10 NULL 31
  2. B10 20 3112 9 31
  3. C11 20 NULL14 8 NULL
  4. D10 20 3111 20 NULL12 9 3114 8 NULL
  5. E10 NULL 32
Revelar gabarito e comentário

GabaritoE — 10 NULL 32

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

DELETE com subconsulta correlacionada e o tratamento de NULL

Gabarito: letra E. O comando DELETE remove todas as linhas cujo valor da coluna B tenha pelo menos uma ocorrência na tabela — e, como todo valor não nulo aparece ao menos uma vez, todas as linhas com B não nulo são apagadas. A única linha que sobrevive é aquela em que B é NULL, pois a comparação NULL = NULL não é verdadeira, fazendo com que a subconsulta retorne 0 para essa linha. O resultado final é a linha 10 NULL 32, exatamente a alternativa E.

O que está acontecendo no comando

O comando DELETE usa uma subconsulta correlacionada no WHERE. Isso significa que, para cada linha da tabela R1, a subconsulta é executada de novo, referenciando a linha atual por meio do alias R1 (a tabela externa) e do alias x (a tabela interna, que é a mesma R1). A condição R1.B = x.B compara o valor de B da linha externa com o valor de B de cada linha da tabela interna.

A subconsulta conta quantas linhas da tabela têm o mesmo valor de B que a linha atual. Se essa contagem for maior que zero, a linha externa é deletada. Como cada valor não nulo de B aparece pelo menos uma vez na tabela (a própria linha atual conta), a condição > 0 é verdadeira para todas as linhas com B não nulo.

O papel crucial do NULL

Aqui está o ponto central da questão: NULL não é um valor. Na lógica de três valores do SQL, qualquer comparação com NULL resulta em UNKNOWN, que não é nem verdadeiro nem falso. Portanto, NULL = NULL não é verdadeiro — é UNKNOWN. A subconsulta, ao comparar R1.B = x.B para a linha onde B é NULL, nunca encontra uma correspondência verdadeira, então o COUNT(*) retorna 0 para essa linha. Como 0 não é maior que 0, a condição do WHERE é falsa e a linha com NULL não é deletada.

Vamos verificar linha por linha. Suponha a tabela R1 com as seguintes linhas (valores de A, B, C):

  • (10, 20, 31)

  • (11, 20, NULL)

  • (12, 9, 31)

  • (14, 8, NULL)

  • (10, NULL, 32)

Para a linha (10, 20, 31): a subconsulta conta quantas linhas têm B = 20. Existem duas (a própria e a (11, 20, NULL)), então COUNT(*) = 2 > 0 → deleta.

Para a linha (11, 20, NULL): idem, B = 20 aparece duas vezes → deleta.

Para a linha (12, 9, 31): B = 9 aparece uma vez → deleta.

Para a linha (14, 8, NULL): B = 8 aparece uma vez → deleta.

Para a linha (10, NULL, 32): a subconsulta conta quantas linhas têm B = NULL. A comparação NULL = NULL nunca é verdadeira, então COUNT(*) = 0, que não é maior que 0 → não deleta.

A pegadinha da banca

A banca explora exatamente a confusão entre "o valor NULL aparece uma vez" e "NULL = NULL é verdadeiro". O candidato desatento conta que o NULL aparece uma vez e acha que a linha seria deletada, sobrando zero linhas. Mas a semântica correta do SQL é que NULL não é igual a nada, nem a si mesmo. Essa é uma pegadinha clássica em provas de banco de dados.

NÃO CAIA NESSA!

A banca conta com o candidato que esquece que NULL = NULL não é verdadeiro no SQL. A linha com B nulo não é deletada, porque a subconsulta retorna 0 para ela. Se você marcou qualquer alternativa que não inclui a linha 10 NULL 32, caiu exatamente nessa armadilha.

Alternativa A — ❌ Incorreta

A alternativa A traz apenas a linha 10 NULL 31. O valor de C está errado (deveria ser 32, não 31) e, além disso, ela omite a linha correta. O erro aqui é duplo: o valor de C foi trocado e a linha não corresponde à que realmente sobrevive.

Alternativa B — ❌ Incorreta

A alternativa B traz as linhas 10 20 31 e 12 9 31. Essas linhas têm B não nulo (20 e 9), portanto seriam deletadas pelo comando. A alternativa está incorreta porque mantém linhas que deveriam ser removidas.

Alternativa C — ❌ Incorreta

A alternativa C traz as linhas 11 20 NULL e 14 8 NULL. Ambas têm B não nulo (20 e 8), então também seriam deletadas. A alternativa está incorreta pelo mesmo motivo da B: mantém linhas que o comando remove.

Alternativa D — ❌ Incorreta

A alternativa D traz quatro linhas: 10 20 31, 11 20 NULL, 12 9 31 e 14 8 NULL. Todas têm B não nulo e seriam deletadas. A alternativa está incorreta porque mantém todas as linhas que deveriam ser removidas, deixando de fora apenas a linha com NULL.

Alternativa E — ✅ Correta ⟵ GABARITO

A alternativa E traz a linha 10 NULL 32. Essa é exatamente a linha que sobrevive ao comando, pois seu valor de B é NULL e a subconsulta retorna 0 para ela, não satisfazendo a condição > 0. As demais linhas, com B não nulo, são todas deletadas.

Gabarito: letra E

Link permanente: /questoes/fg063595