Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2023

Banco de DadosConsultas 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.

Imagem associada para resolução da questão

Nesse cenário analise os comandos a seguir.

 

I.

Imagem associada para resolução da questão

II.

Imagem associada para resolução da questão

III.

Imagem associada para resolução da questão

 

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.

  1. A2, 2 e 0.
  2. B2, 4 e 0.
  3. C4, 4 e 4.
  4. D6, 5 e 6.
  5. 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.

DELETEFROMRWHEREEXISTS(SELECTFROMRASR1WHERER.A=R1.AANDR.B=R1.B)DELETE FROM R WHERE EXISTS (SELECT * FROM R AS R1 WHERE R.A = R1.A AND R.B = R1.B)

De onde vem cada valor: R.AR.A = enunciado: coluna A da tabela R · R1.AR1.A = enunciado: coluna A da tabela R com alias R1 · R.BR.B = enunciado: coluna B da tabela R · R1.BR1.B = 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.

DELETEFROMRWHEREEXISTS(SELECTFROMRASR1WHERER.A=R1.AANDR.B<>R1.B)DELETE FROM R WHERE EXISTS (SELECT * FROM R AS R1 WHERE R.A = R1.A AND R.B <> R1.B)

De onde vem cada valor: R.AR.A = enunciado: coluna A da tabela R · R1.AR1.A = enunciado: coluna A da tabela R com alias R1 · R.BR.B = enunciado: coluna B da tabela R · R1.BR1.B = 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.

DELETEFROMRWHERENOTEXISTS(SELECTFROMRASR1WHERER.A=R1.AANDR.B=R1.BANDR.A<>R1.A)DELETE FROM R WHERE NOT EXISTS (SELECT * FROM R AS R1 WHERE R.A = R1.A AND R.B = R1.B AND R.A <> R1.A)

De onde vem cada valor: R.AR.A = enunciado: coluna A da tabela R · R1.AR1.A = enunciado: coluna A da tabela R com alias R1 · R.BR.B = enunciado: coluna B da tabela R · R1.BR1.B = 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.

Resposta: 6, 5 e 6 — alternativa D

Link permanente: /questoes/fg161096