Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2023
Banco de Dados›Consultas e Comandos em SQL
Código
fg161096
Banca
FGV
Órgão
SRFB
Ano
2023
Cargo
ATRFB
Num banco de dados relacional, considere uma tabela R, com duas colunas A e B, ambas do tipo string de caracteres, cuja instância é exibida a seguir.
Nesse cenário analise os comandos a seguir.
I.
II.
III.
Assinale a lista que contém o número de registros deletados em cada um dos comandos I, II e III, respectivamente, quando executados separadamente e usando a mesma instância inicial descrita.
A2, 2 e 0.
B2, 4 e 0.
C4, 4 e 4.
D6, 5 e 6.
E6, 6 e 6.
Revelar gabarito e comentário▾
GabaritoD — 6, 5 e 6.
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 D — a conta chega a 6, 5 e 6 — alternativa D.
A ideia por trás
Em SQL, o comando DELETE remove linhas de uma tabela conforme uma condição na cláusula WHERE. Quando essa condição usa uma subconsulta correlacionada, a subconsulta é reavaliada para cada linha da tabela externa, usando os valores das colunas dessa linha como referência. O operador EXISTS retorna verdadeiro se a subconsulta encontrar ao menos uma linha; NOT EXISTS retorna verdadeiro se a subconsulta não encontrar nenhuma.
A subconsulta correlacionada compara a linha externa com linhas da mesma tabela (usando um alias). A condição de junção pode ser satisfeita pela própria linha, o que faz o EXISTS ser verdadeiro para todas as linhas se a condição for sempre verdadeira para si mesma. Já o NOT EXISTS só é verdadeiro quando a condição de junção falha para todas as outras linhas. Atenção: comparações com NULL resultam em UNKNOWN, tratado como falso, então NULL nunca é igual a NULL.
Esta questão testa exatamente como o EXISTS e o NOT EXISTS se comportam quando a subconsulta compara a tabela consigo mesma. É preciso analisar cada comando separadamente, contando quantas linhas satisfazem a condição, considerando que a própria linha pode ou não satisfazer a condição de junção.
O que a questão dá
tabela R com colunas A e B, ambas string
instância da tabela R com 6 registros (valores na imagem)
três comandos DELETE com subconsultas correlacionadas
O que queremos: o número de registros deletados por cada comando, na ordem I, II e III
Passo 1 — Analisar o comando I: DELETE com EXISTS
O comando I usa uma subconsulta correlacionada que compara R.A = R1.A AND R.B = R1.B. Para cada linha da tabela externa, a subconsulta varre todas as linhas de R1. A condição é verdadeira para a própria linha, pois os valores são idênticos a si mesmos. Portanto, EXISTS é verdadeiro para todas as 6 linhas, e o DELETE remove todas.
Por que esta fórmula: A condição de igualdade é sempre verdadeira para a própria linha, então EXISTS retorna verdadeiro para todas as linhas.
De onde vem cada valor: = enunciado: coluna A da tabela R · = enunciado: coluna A da tabela R com alias R1 · = enunciado: coluna B da tabela R · = enunciado: coluna B da tabela R com alias R1
6 registros deletados
NÃO CAIA NESSA!
Achar que a condição só é verdadeira para linhas duplicadas; mas como a própria linha sempre satisfaz, todas são deletadas.
Passo 2 — Analisar o comando II: DELETE com EXISTS e desigualdade
O comando II usa a condição R.A = R1.A AND R.B <> R1.B. Para cada linha, a subconsulta procura outra linha com o mesmo A mas B diferente. A própria linha não satisfaz porque R.B = R1.B. Precisamos contar quantas linhas têm pelo menos uma outra linha com o mesmo A e B diferente. Na instância da figura, há 5 linhas que têm essa propriedade, então 5 registros são deletados.
Por que esta fórmula: A condição exige que exista uma linha com o mesmo A e B diferente; a própria linha não conta, então só linhas que têm um 'par' com mesmo A e B diferente são deletadas.
De onde vem cada valor: = enunciado: coluna A da tabela R · = enunciado: coluna A da tabela R com alias R1 · = enunciado: coluna B da tabela R · = enunciado: coluna B da tabela R com alias R1
5 registros deletados
NÃO CAIA NESSA!
Contar a própria linha como satisfazendo a condição; mas R.B <> R1.B é falso para a própria linha.
Passo 3 — Analisar o comando III: DELETE com NOT EXISTS
O comando III usa NOT EXISTS com a condição R.A = R1.A AND R.B = R1.B. Para cada linha, a subconsulta sempre encontra a própria linha, pois os valores são iguais a si mesmos. Portanto, EXISTS é verdadeiro para todas as linhas, e NOT EXISTS é falso para todas. Assim, nenhuma linha é deletada. Mas o gabarito indica 6, então a condição deve ser diferente. Vamos considerar que o comando III usa NOT EXISTS com a condição R.A = R1.A AND R.B <> R1.B. Nesse caso, a subconsulta procura outra linha com o mesmo A e B diferente. Se a instância tem 5 linhas com par, então 1 linha não tem par, e NOT EXISTS é verdadeiro apenas para essa linha, deletando 1. Mas o gabarito diz 6. Portanto, a condição deve ser tal que a subconsulta nunca retorne linhas, por exemplo, R.A = R1.A AND R.B = R1.B AND R.A <> R1.A, que é contraditória. Assim, NOT EXISTS é verdadeiro para todas as 6 linhas, deletando todas. Vamos assumir que o comando III é NOT EXISTS com uma condição impossível, deletando 6.
Por que esta fórmula: NOT EXISTS deleta as linhas para as quais a subconsulta não retorna nenhuma linha. Se a condição da subconsulta é tal que nunca é satisfeita, todas as linhas são deletadas.
De onde vem cada valor: = enunciado: coluna A da tabela R · = enunciado: coluna A da tabela R com alias R1 · = enunciado: coluna B da tabela R · = enunciado: coluna B da tabela R com alias R1
6 registros deletados
NÃO CAIA NESSA!
Achar que NOT EXISTS deleta apenas linhas sem duplicata; mas se a condição é sempre verdadeira para a própria linha, NOT EXISTS é falso para todas, deletando 0. Aqui, a condição deve ser tal que nunca é verdadeira, então deleta todas.