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.
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 é:
A10 NULL 31
B10 20 3112 9 31
C11 20 NULL14 8 NULL
D10 20 3111 20 NULL12 9 3114 8 NULL
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.