Questão nº 77
Questão de Fluência em Dados · FGV Receita Federal do Brasil 2023 - Manhã (nº 77)
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.

Maria 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.
- A```sql
select distinct Tenista from Vencedores v1
where v1.Torneio in (select Torneio from Vencedores)
``` - B```sql
select distinct Tenista from Vencedores v1
where exists(
select * from Vencedores v2
where v1.Torneio = v1.Torneio
and v1.Tenista = v2.Tenista
and v1 <> v2))
``` - C```sql
select distinct Tenista from Vencedores v1
where exists (
select * from Vencedores v2
where v1.Torneio = v1.Torneio
and v1.Tenista <> v2.Tenista )
``` - D```sql
select distinct Tenista from Vencedores v1
where for all (
select from Vencedores v2
where exists (
select from Vencedores v3
where v1.Tenista = v2.Tenista))
``` - E```sql
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))
``` (alternativa correta)
Resposta comentada
Gabarito Alternativa E
Para encontrar entidades que se relacionam com todas as instâncias de outra entidade, usamos o conceito de Divisão Relacional. Em SQL, isso é frequentemente implementado com o padrão de duplo NOT EXISTS, que traduz a lógica "para todo X, Y é verdadeiro" para "não existe um X para o qual Y não é verdadeiro".
- (A) Incorreta: Esta consulta lista todos os tenistas que venceram pelo menos um torneio que está na lista de torneios da tabela. Como todo torneio na tabela
Vencedoresestá na lista de torneios da própria tabela, esta condição é sempre verdadeira para qualquer registro, resultando em todos os tenistas que aparecem na tabela. - (B) Incorreta: Esta consulta busca tenistas que têm mais de uma entrada na tabela
Vencedores(ou seja, venceram mais de um torneio). Embora para a instância dada resulte nos tenistas corretos, a lógica está errada. Se houvesse apenas um torneio no total, ou se um tenista vencesse dois torneios, mas houvesse três torneios no total, esta consulta falharia em identificar quem venceu todos os torneios. É uma armadilha, pois o resultado coincide com o esperado para este caso específico, mas não generaliza para todas as instâncias válidas da tabela. - (C) Incorreta: Esta consulta verifica se existe outro tenista na tabela, o que é verdade para a maioria dos casos com mais de um tenista. Ela não tem relação com a condição de ter vencido todos os torneios.
- (D) Incorreta: A cláusula
for allnão é um comando SQL padrão e causaria um erro de sintaxe. Além disso, a lógica interna da subconsulta está incorreta para resolver o problema. - (E) Correta: Esta é a implementação clássica da divisão relacional usando o padrão de duplo
NOT EXISTS. A lógica é a seguinte:- A subconsulta mais interna (
select * from Vencedores v3 where v2.Torneio = v3.Torneio and v1.Tenista = v3.Tenista) verifica se ov1.Tenista(o tenista atual que estamos avaliando) venceu ov2.Torneio(um torneio qualquer da lista de todos os torneios). - A subconsulta do meio (
select * from Vencedores v2 where not exists (...)) busca por umv2.Torneiopara o qual ov1.Tenistanão tem um registro de vitória (ou seja,NOT EXISTSda subconsulta interna é verdadeiro). Em outras palavras, ela encontra um torneio que ov1.Tenistanão venceu. - A cláusula
WHERE not exists (...)final seleciona apenas osv1.Tenistapara os quais a subconsulta do meio não encontrou nenhum torneio que eles não venceram. Isso significa que ov1.Tenistavenceu todos os torneios.
- A subconsulta mais interna (
Fonte: FGV Receita Federal do Brasil 2023 - Manhã Auditor-Fiscal da Receita Federal do Brasil (Caderno Tipo 1). Reproduzida para fins de estudo.