Pular para o conteúdo principal

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

Banco de DadosSQL
Código
fg067882
Banca
FGV
Órgão
Receita Federal
Ano
2023
Nível
Superior
Cargo
Auditor-Fiscal (manhã)
Num banco de dados relacional, considere a tabela Vencedores, cuja instância é exibida a seguir, com duas colunas, Tenista e Torneio, que representam alguns torneios que já foram vencidos por alguns tenistas.Tenista TorneioRoger Federer Australian OpenRoger Federer Roland GarrosRoger Federer WimbledonRoger Federer US OpenPete Sampras US OpenPete Sampras WimbledonPete Sampras Australian OpenBjorn Borg Roland GarrosBjorn Borg WimbledonMaria precisa escrever um comando SQL que liste os tenistas que venceram todos os torneios mencionados na coluna Torneio. O comando deve valer para qualquer instância válida da tabela, que pode conter diferentes tenistas e diferentes torneios.Assinale o comando que Maria deve usar.
  1. Aselect distinct Tenista from Vencedores v1where v1.Torneio in (select Torneio from Vencedores)
  2. Bselect distinct Tenista from Vencedores v1where exists(select * from Vencedores v2where v1.Torneio = v1.Torneioand v1.Tenista = v2.Tenistaand v1 <> v2))
  3. Cselect distinct Tenista from Vencedores v1where exists (select * from Vencedores v2where v1.Torneio = v1.Torneioand v1.Tenista <> v2.Tenista )
  4. Dselect distinct Tenista from Vencedores v1where for all (select * from Vencedores v2where exists (select * from Vencedores v3where v1.Tenista = v2.Tenista))
  5. Eselect distinct Tenista from Vencedores v1where not exists(select * from Vencedores v2where not exists (select * from Vencedores v3where v2.Torneio = v3.Torneioand v1.Tenista = v3.Tenista))
Revelar gabarito e comentário

GabaritoE — select distinct Tenista from Vencedores v1 where not exists( select * from Vencedores v2 where not exists ( select * from Vencedores v3 where v2.Torneio = v3.Torneio and v1.Tenista = v3.Tenista))

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

Divisão relacional em SQL: tenistas que venceram todos os torneios

Gabarito: letra E. A consulta correta utiliza dupla negação com NOT EXISTS aninhados: para cada tenista, verifica-se que não existe nenhum torneio que ele não tenha vencido. Esse padrão implementa a divisão relacional (relational division) em SQL.

A banca testa o conhecimento da técnica de divisão relacional, que exige o uso de subconsultas correlacionadas. A alternativa E é a única que implementa corretamente a lógica: "selecione os tenistas para os quais não existe um torneio que não tenha sido vencido por eles".

Alternativa A — ❌ Incorreta

A subconsulta retorna todos os torneios, e o IN verifica se o torneio da linha externa está nessa lista, o que é sempre verdade (já que todos os torneios existem). O DISTINCT então retorna todos os tenistas que aparecem na tabela, independentemente de terem vencido todos os torneios. Erro: retorna qualquer tenista, não apenas os que venceram todos.

Alternativa B — ❌ Incorreta

A condição v1.Torneio = v1.Torneio é sempre verdadeira e v1 <> v2 compara linhas (não padrão SQL). O EXISTS verifica se existe pelo menos um outro registro do mesmo tenista (v1.Tenista = v2.Tenista), o que retorna tenistas com mais de um torneio, mas não todos. Além disso, a sintaxe v1 <> v2 é problemática.

Alternativa C — ❌ Incorreta

Novamente v1.Torneio = v1.Torneio é tautologia. A condição v1.Tenista <> v2.Tenista verifica se existe outro tenista vencendo algum torneio. O resultado inclui qualquer tenista que apareça junto com outro, o que é praticamente todos. Não há garantia de que o tenista venceu todos os torneios.

Alternativa D — ❌ Incorreta

FOR ALL não é um operador SQL válido. A sintaxe está incorreta, portanto a consulta não executaria.

Alternativa E — ✅ Correta ⟵ GABARITO

A lógica é a seguinte:

  1. Subconsulta mais interna: para um determinado tenista v1 e um torneio v2, verifica se existe um registro v3 com aquele torneio e aquele tenista (v2.Torneio = v3.Torneio AND v1.Tenista = v3.Tenista).

  2. Subconsulta intermediária: NOT EXISTS seleciona os torneios (v2) para os quais a subconsulta interna não retorna nada, ou seja, torneios que o tenista NÃO venceu.

  3. Consulta externa: NOT EXISTS seleciona os tenistas para os quais a subconsulta intermediária não retorna nenhum torneio, ou seja, não existe torneio não vencido — portanto, o tenista venceu todos os torneios.

Essa é a técnica padrão de divisão relacional em SQL, equivalente a "todos os torneios".

Link permanente: /questoes/fg067882