Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2023
Banco de Dados›Consultas e Comandos em SQL
Código
fg161110
Banca
FGV
Órgão
DPE RS
Ano
2023
Cargo
Ana ( )
Tabela R1
Na questão a seguir, considere a tabela R1, cuja instância é exibida a seguir.
A
B
C
10
20
31
10
NULL
32
11
20
NULL
12
9
31
14
8
NULL
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 31 12 9 31
C11 20 NULL 14 8 NULL
D10 20 31 11 20 NULL 12 9 31 14 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 valores NULL
Gabarito: letra E. O comando DELETE remove todas as linhas de R1 cujo valor de B tenha alguma ocorrência duplicada na própria tabela (incluindo a linha atual). Como os valores 20 e 9 aparecem mais de uma vez, as linhas com B = 20 (duas linhas) e B = 9 (uma linha) são excluídas, restando apenas a linha (10, NULL, 32) — exatamente a alternativa E.
O comando DELETE com subconsulta correlacionada é uma das pegadinhas mais clássicas de SQL em concursos. A subconsulta (select count(*) from R1 x where R1.B = x.B) é avaliada para cada linha da tabela externa R1. Para cada linha, ela conta quantas linhas da tabela (com o apelido x) possuem o mesmo valor de B que a linha atual. Se essa contagem for maior que zero, a linha é deletada.
O ponto crucial é entender que a comparação R1.B = x.Bnunca é verdadeira quando B é NULL. Em SQL, qualquer comparação com NULL resulta em UNKNOWN, que não é considerado verdadeiro na cláusula WHERE. Portanto, a linha com B = NULL não é contada na subconsulta e, consequentemente, não é deletada.
Vamos analisar linha por linha da tabela R1:
Linha
A
B
C
Contagem de B duplicado
Deletada?
1
10
20
31
2 (linhas 1 e 2)
Sim
2
10
NULL
32
0 (NULL não conta)
Não
3
11
20
NULL
2 (linhas 1 e 2)
Sim
4
12
9
31
1 (linha 4)
Sim
5
14
8
NULL
1 (linha 5)
Sim
Perceba que a linha 4 (B = 9) é deletada porque existe uma outra linha com B = 9 (ela mesma). A condição > 0 é satisfeita mesmo que a contagem seja 1, pois a subconsulta conta a própria linha. Isso é um detalhe sutil: a subconsulta correlacionada conta todas as linhas com o mesmo B, incluindo a linha atual. Portanto, qualquer valor de B que apareça pelo menos uma vez (ou seja, qualquer valor não-NULL) será deletado.
A única linha que escapa é a que tem B = NULL, porque a comparação NULL = NULL não é verdadeira em SQL. Isso é uma das propriedades fundamentais do NULL: ele não é igual a nada, nem a ele mesmo. Por isso, a linha (10, NULL, 32) permanece na tabela.
NÃO CAIA NESSA!
A banca explora a confusão entre NULL e um valor comum. Muitos candidatos assumem que NULL = NULL é verdadeiro, mas em SQL essa comparação resulta em UNKNOWN, que não satisfaz a condição WHERE. A linha com B = NULL não é contada na subconsulta e, portanto, não é deletada. É exatamente essa linha que sobra na resposta.
Alternativa A — ❌ Incorreta
Apresenta a linha (10, NULL, 31), que não existe na tabela original. A linha com A = 10 e B = NULL tem C = 32, não 31. Além disso, essa alternativa sugere que a linha com B = NULL seria modificada, o que não ocorre — o DELETE remove linhas inteiras, não altera valores.
Alternativa B — ❌ Incorreta
Mantém as linhas (10, 20, 31) e (12, 9, 31), mas ambas deveriam ser deletadas. A linha com B = 20 tem duplicata (a linha com B = 20 e A = 11), e a linha com B = 9 tem duplicata (ela mesma). A condição > 0 é satisfeita para ambas, então elas são removidas.
Alternativa C — ❌ Incorreta
Mantém as linhas (11, 20, NULL) e (14, 8, NULL), mas ambas deveriam ser deletadas. A linha com B = 20 tem duplicata, e a linha com B = 8 tem duplicata (ela mesma). A condição > 0 é satisfeita para ambas, então elas são removidas.
Alternativa D — ❌ Incorreta
Mantém todas as linhas exceto a que tem B = NULL. Isso seria o resultado se a condição fosse > 1 (exigindo pelo menos uma duplicata além da própria linha), mas a condição é > 0, que é satisfeita por qualquer valor não-NULL. Portanto, todas as linhas com B não-NULL são deletadas.
Alternativa E — ✅ Correta ⟵ GABARITO
A única linha que permanece é (10, NULL, 32), pois a comparação R1.B = x.B nunca é verdadeira quando B é NULL. A subconsulta retorna contagem 0 para essa linha, e a condição > 0 não é satisfeita. Todas as outras linhas têm B não-NULL e são deletadas.
PEGA ESSA DICA!
Em SQL, qualquer comparação com NULL resulta em UNKNOWN, que não é considerado verdadeiro na cláusula WHERE. Isso significa que NULL = NULL é falso, NULL <> NULL também é falso, e até NULL IS NULL é a única forma de testar NULL. Quando uma questão envolve DELETE ou SELECT com subconsultas correlacionadas, verifique sempre se há valores NULL envolvidos — eles frequentemente escapam da condição.
Gabarito: letra E — a única linha restante é (10, NULL, 32).