Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024
Banco de Dados›Consultas e Comandos em SQL
Código
fg165225
Banca
FGV
Órgão
ALEP
Ano
2024
Cargo
Ana Leg ( )
Considere o esquema relacional a seguir, implementado em SQL. create table recurso ( id integer primary key, nome varchar(20) not null, valor real ); create table projeto ( id integer primary key, nome varchar(20) not null, verba real ); create table alocacao ( id_recurso integer, id_projeto integer, primary key(id_recurso,id_projeto), foreign key(id_recurso) references recurso, foreign key(id_projeto) references projeto ); Assinale a opção que apresenta a consulta que gera como resultado de execução uma lista com o nome dos recursos alocados em todos os projetos cadastrados.
Aselect r.nome from recurso r
Bselect r.nome from recurso r where not exists (select 1 from alocacao a where a.id_recurso=r.id )
Cselect r.nome from recurso r where r.valor>(select avg(valor) from recurso)
Dselect r.nome from recurso r where not exists (select 1 from projeto p where not exists (select 0 from alocacao a where a.id_recurso=r.id and a.id_projeto=p.id ) )
Eselect r.nome from recurso r where exists (select 1 from alocacao a where a.id_recurso=r.id )
Revelar gabarito e comentário▾
GabaritoD — select r.nome from recurso r where not exists (select 1 from projeto p where not exists (select 0 from alocacao a where a.id_recurso=r.id and a.id_projeto=p.id ) )
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”.
Consultas SQL com quantificador universal: recursos alocados em todos os projetos
Gabarito: letra D. A consulta correta usa uma dupla negação com NOT EXISTS para expressar a divisão relacional: seleciona o recurso r para o qual não existe um projeto p que não tenha uma alocação com esse recurso. Em outras palavras, o recurso está alocado em todos os projetos cadastrados. As demais alternativas ou listam todos os recursos, ou apenas os que têm/não têm alguma alocação, sem verificar a totalidade dos projetos.
O problema pede uma consulta que responda a uma pergunta com quantificador universal: "para todo projeto, existe uma alocação deste recurso". Em SQL, não há um operador direto de divisão (como na álgebra relacional), mas a dupla negação com NOT EXISTS resolve: NOT EXISTS (SELECT 1 FROM projeto p WHERE NOT EXISTS (SELECT 0 FROM alocacao a WHERE a.id_recurso = r.id AND a.id_projeto = p.id)). A lógica é: se não existe um projeto para o qual não exista alocação, então o recurso está em todos. É o padrão clássico para consultas "todos" em SQL.
Para entender por que as outras falham, é preciso distinguir três situações: (1) recursos com pelo menos uma alocação — usa EXISTS simples; (2) recursos sem nenhuma alocação — usa NOT EXISTS simples; (3) recursos alocados em todos os projetos — exige a dupla negação. A alternativa E pega o caso (1), a B pega o caso (2), a A pega todos os recursos sem filtro, e a C filtra por valor acima da média — nenhuma delas verifica a totalidade dos projetos.
Um exemplo concreto: suponha os projetos P1 e P2, e os recursos R1 (alocado em P1 e P2), R2 (alocado só em P1) e R3 (sem alocação). A consulta correta retorna apenas R1. A alternativa E retornaria R1 e R2 (têm pelo menos uma alocação); a B retornaria R3 (não tem alocação); a A retornaria R1, R2 e R3; a C depende do valor, mas não da alocação. A dupla negação é a única que exige que o recurso esteja presente em todos os projetos.
A pegadinha da banca está em confundir "alocado em todos" com "alocado em pelo menos um". O candidato apressado marca a letra E, que usa EXISTS simples, mas ela não garante a totalidade. A letra D, com a dupla negação, é a tradução fiel do quantificador universal. Guarde o padrão: para "todos", use NOT EXISTS aninhado.
1EXISTS simples
2pelo menos um
3NOT EXISTS simples
4nenhum
5NOT EXISTS duplo
6todos (divisão)
LEVEL · soulevel.com.br
Alternativa A — ❌ Incorreta
select r.nome from recurso r simplesmente lista o nome de todos os recursos da tabela recurso, sem qualquer condição de alocação. Não verifica se o recurso está alocado em algum projeto, muito menos em todos. O erro é a ausência total de filtro — retorna inclusive recursos sem nenhuma alocação.
Alternativa B — ❌ Incorreta
select r.nome from recurso r where not exists (select 1 from alocacao a where a.id_recurso=r.id) seleciona os recursos que não possuem nenhuma alocação (a subconsulta verifica se existe alguma alocação para o recurso; a negação traz os que não têm). Isso é o oposto do pedido: retorna recursos não alocados em nenhum projeto, enquanto a questão quer os alocados em todos.
Alternativa C — ❌ Incorreta
select r.nome from recurso r where r.valor>(select avg(valor) from recurso) filtra recursos cujo valor é maior que a média de valor de todos os recursos. Essa consulta não tem nenhuma relação com a tabela alocacao ou projeto — é um filtro puramente numérico sobre a coluna valor. Não verifica alocação em projetos, portanto não atende ao enunciado.
Alternativa D — ✅ Correta ⟵ GABARITO
select r.nome from recurso r where not exists (select 1 from projeto p where not exists (select 0 from alocacao a where a.id_recurso=r.id and a.id_projeto=p.id )) implementa a divisão relacional por dupla negação. A subconsulta mais interna verifica se existe uma alocação do recurso r no projeto p. A negação externa (not exists sobre projeto) verifica se existe algum projeto p para o qual não existe essa alocação. Se não existe tal projeto, então o recurso está alocado em todos os projetos. É exatamente o que o enunciado pede.
Alternativa E — ❌ Incorreta
select r.nome from recurso r where exists (select 1 from alocacao a where a.id_recurso=r.id) seleciona os recursos que possuem pelo menos uma alocação (a subconsulta verifica se existe alguma alocação para o recurso). Isso retorna recursos alocados em um ou mais projetos, mas não garante que estejam em todos. É a pegadinha clássica: confunde "existe alocação" com "alocado em todos".
NÃO CAIA NESSA!
A banca explora a confusão entre o quantificador existencial (EXISTS) e o universal ("todos"). A alternativa E parece correta à primeira vista, mas só verifica se o recurso tem alguma alocação. Para exigir "todos", é preciso a dupla negação com NOT EXISTS aninhado, como na letra D. Na prova, desconfie de consultas com EXISTS simples quando o enunciado pedir "todos" — o padrão correto é sempre o NOT EXISTS duplo.
PEGA ESSA DICA!
Para identificar a consulta de "todos" em SQL, procure pela estrutura NOT EXISTS (SELECT ... FROM projeto p WHERE NOT EXISTS (SELECT ... FROM alocacao a WHERE ...)). Essa é a tradução direta da divisão relacional. Memorize o padrão: "não existe projeto sem alocação" = alocado em todos. Compare com o EXISTS simples (pelo menos um) e o NOT EXISTS simples (nenhum).