Considere o esquema relacional a seguir, implementado em SQL.
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 subconsultas correlacionadas: EXISTS e NOT EXISTS
Gabarito: letra D. A consulta que retorna o nome dos recursos alocados em todos os projetos cadastrados é a que usa dupla negação com NOT EXISTS: para cada recurso, verifica se não existe um projeto para o qual não exista uma alocação — ou seja, o recurso está alocado em todos os projetos. Essa é a técnica clássica de divisão relacional em SQL, e a alternativa D a implementa corretamente.
O problema pede uma operação de divisão relacional: encontrar os recursos que estão associados a todos os projetos. Em SQL, isso não é direto como um JOIN ou um WHERE simples — exige uma construção com subconsultas correlacionadas e dupla negação. A lógica é: um recurso está em todos os projetos se não existe nenhum projeto em que ele não esteja alocado. Em SQL, isso se escreve com NOT EXISTS aninhado: o NOT EXISTS externo testa se a subconsulta interna (que procura um projeto sem alocação) retorna vazio. Se retornar vazio, o recurso passa no filtro.
Vamos entender cada peça:
EXISTS (subconsulta) retorna verdadeiro se a subconsulta retorna pelo menos uma linha.
NOT EXISTS (subconsulta) retorna verdadeiro se a subconsulta retorna nenhuma linha.
Quando a subconsulta é correlacionada (referencia a linha externa, como r.id), o EXISTS/NOT EXISTS é avaliado para cada linha da consulta externa.
A alternativa D usa exatamente isso:
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
)
)
Para cada recurso r, a subconsulta mais interna procura uma alocação desse recurso em um projeto p. Se não existir tal alocação para algum projeto, o NOT EXISTS interno retorna verdadeiro, e o NOT EXISTS externo retorna falso — o recurso é descartado. Se todos os projetos tiverem alocação, o NOT EXISTS interno retorna falso para todos, e o NOT EXISTS externo retorna verdadeiro — o recurso é incluído. É a divisão relacional.
As demais alternativas cometem erros típicos:
A retorna todos os recursos, sem filtro.
B retorna recursos que não têm nenhuma alocação (o oposto do que se quer).
C retorna recursos com valor acima da média — critério irrelevante.
E retorna recursos que têm pelo menos uma alocação — não necessariamente em todos os projetos.
A pegadinha da banca é confundir "alocado em todos" com "alocado em pelo menos um". A alternativa E parece razoável, mas responde a pergunta errada. A alternativa D é a única que implementa a divisão relacional corretamente.
NÃO CAIA NESSA!
A banca troca "todos" por "pelo menos um". A alternativa E (exists) retorna recursos com qualquer alocação, não com alocação em todos os projetos. A alternativa B (not exists) retorna recursos sem nenhuma alocação. A alternativa D é a única que usa a dupla negação para exigir que o recurso esteja em todos os projetos.
Divisão relacional em SQL: Objetivo (Recursos alocados em TODOS os projetos); Técnica (Dupla negação com NOT EXISTS, "Não existe projeto sem alocação"); EXISTS (Retorna verdadeiro se há ≥1 linha); NOT EXISTS (Retorna verdadeiro se não há linhas); Erros comuns (EXISTS (pelo menos um), NOT EXISTS (nenhum), Sem filtro (todos))
Alternativa A — ❌ Incorreta
select r.nome from recurso r simplesmente lista todos os recursos da tabela, sem qualquer condição de alocação. Não filtra por projetos — retorna inclusive recursos nunca alocados. Claramente não atende ao pedido.
Alternativa B — ❌ Incorreta
where not exists (select 1 from alocacao a where a.id_recurso = r.id) retorna os recursos que não possuem nenhuma alocação — exatamente o oposto do que se quer. É o complemento da alternativa E: em vez de recursos alocados, traz os não alocados.
Alternativa C — ❌ Incorreta
where r.valor > (select avg(valor) from recurso) filtra recursos cujo valor é acima da média de todos os recursos. Esse critério não tem relação alguma com alocação em projetos — é um distrator que mistura agregação (AVG) com o tema de alocação.
Alternativa D — ✅ Correta ⟵ GABARITO
Como explicado, a dupla negação com NOT EXISTS implementa a divisão relacional: seleciona recursos para os quais não existe um projeto sem alocação. É a resposta correta.
Alternativa E — ❌ Incorreta
where exists (select 1 from alocacao a where a.id_recurso = r.id) retorna recursos que possuem pelo menos uma alocação. Isso garante que o recurso está em algum projeto, mas não em todos. É a pegadinha clássica: parece certa, mas responde "alocado em algum projeto", não "alocado em todos os projetos".