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 Torneio Roger Federer Australian Open Roger Federer Roland Garros Roger Federer Wimbledon Roger Federer US Open Pete Sampras US Open Pete Sampras Wimbledon Pete Sampras Australian Open Bjorn Borg Roland Garros Bjorn Borg Wimbledon 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)select distinct Tenista from Vencedores v1 where v1.Torneio in (select Torneio from Vencedores)
Errada, porque apenas filtra linhas cujo torneio aparece na tabela e não verifica se o tenista venceu todos os torneios.
- B)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))
Errada, porque a condição v1.Torneio = v1.Torneio é sempre verdadeira e a lógica não garante comparação correta nem cobertura de todos os torneios.
- C)select distinct Tenista from Vencedores v1 where exists ( select * from Vencedores v2 where v1.Torneio = v1.Torneio and v1.Tenista <> v2.Tenista )
Errada, porque além da comparação sem sentido em v1.Torneio = v1.Torneio, ela testa tenistas diferentes, o oposto do que se precisa aqui.
- D)select distinct Tenista from Vencedores v1 where for all ( select * from Vencedores v2 where exists ( select * from Vencedores v3 where v1.Tenista = v2.Tenista))
Errada, porque usa uma construção inexistente em SQL padrão ('for all') e não implementa corretamente a verificação universal.
- E)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))
Certa, porque usa dupla negação para selecionar o tenista para o qual não existe torneio da tabela que ele não tenha vencido.
Gabarito: E
A questão trata de um problema clássico de SQL: encontrar os tenistas que venceram todos os torneios que aparecem na tabela. Em linguagem de prova, isso costuma exigir a ideia de "para todo" (quantificação universal), e no SQL a forma mais segura de simular isso é com dupla negação: procurar um tenista para o qual não exista nenhum torneio da tabela que ele não tenha vencido. É o famoso truque do "não existe torneio faltando". O gabarito é a letra E porque ela faz exatamente isso. Primeiro, para cada tenista de v1, o comando procura torneios em v2 e, depois, verifica se não existe em v3 uma linha com aquele mesmo torneio e aquele mesmo tenista. Se não houver nenhum torneio faltante, o tenista é listado. Essa estrutura corresponde à divisão relacional, um padrão muito cobrado em Banco de Dados. As alternativas erradas não resolvem a ideia de "todos". Algumas só testam existência de linhas, outras comparam colunas de modo incorreto ou trazem sintaxe inválida. Em SQL, quando a banca quer universalidade, desconfie de soluções com EXISTS simples: muitas vezes falta justamente o "NOT EXISTS" externo para garantir que nenhum caso foi esquecido. Em resumo: a resposta certa é a que diz, em português de prova, "liste os tenistas para os quais não há torneio da tabela que não tenha sido vencido por eles". Isso é exatamente o que a letra E expressa.