Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024

Banco de DadosConsultas 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.
  1. Aselect r.nome from recurso r
  2. Bselect r.nome from recurso r where not exists (select 1 from alocacao a where a.id_recurso=r.id )
  3. Cselect r.nome from recurso r where r.valor>(select avg(valor) from recurso)
  4. 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 ) )
  5. 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.

  1. 1EXISTS simples
  2. 2pelo menos um
  3. 3NOT EXISTS simples
  4. 4nenhum
  5. 5NOT EXISTS duplo
  6. 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).

Gabarito: letra D

Link permanente: /questoes/fg165225