Pular para o conteúdo principal

Questão de Banco de Dados — Geral — FGV 2026

Banco de DadosGeral
Código
fg157162
Banca
FGV
Órgão
AMAZUL
Ano
2026
Cargo
TDTND

Considere o seguinte script SQL ANSI para responder à questão.

 

CREATE TABLE PROJETO_PESQUISA
 (
    ID_PROJETO          INTEGER         PRIMARY KEY,
    COD_PROJETO         VARCHAR(30)     UNIQUE,
    TITULO              VARCHAR(200)    NOT NULL,
    AREA_TEMATICA       VARCHAR(100),
    OBJETIVO_GERAL      VARCHAR(1000),
    DATA_INICIO         DATE            NOT NULL,
    DATA_FIM_PREVISTA   DATE,
    STATUS_PROJETO      VARCHAR(30)     NOT NULL
);

 

CREATE TABLE DESENVOLVIMENTO_TECNOLOGICO (
    ID_DESENVOLVIMENTO      INTEGER         PRIMARY KEY,
    ID_PROJETO              INTEGER,
    NOME_RESULTADO          VARCHAR(200)    NOT NULL,
    TIPO_RESULTADO          VARCHAR(50)     NOT NULL,
    NIVEL_MATURIDADE_TEC    INTEGER,
    DATA_INICIO             DATE,
    DATA_CONCLUSAO          DATE,
    SITUACAO                VARCHAR(30),

    CONSTRAINT FK_DESENVOLVIMENTO_PROJETO 
        FOREIGN KEY (ID_PROJETO) 
        REFERENCES PROJETO_PESQUISA (ID_PROJETO)
);

 

Se considerarmos que um script de inserção de dados nas duas tabelas acima seja bem-sucedido, na qual 10 linhas sejam inseridas na tabela PROJETO_PESQUISA e 24 linhas na tabela DESENVOLVIMENTO_TECNOLOGICO.


Na referida inserção, considere que apenas uma tupla da tabela PROJETO_PESQUISA não está associada a alguma tupla da tabela DESENVOLVIMENTO_TECNOLOGICO, e que duas tuplas da tabela DESENVOLVIMENTO_TECNOLOGICO não estão associadas à tabela PROJETO_PESQUISA.

 

Ao analisar a consulta SQL ANSI a seguir:

 

SELECT cod_projeto, titulo

FROM PROJETO_PESQUISA pp

WHERE NOT EXISTS (SELECT id_desenvolvimento

        FROM DESENVOLVIMENTO_TECNOLOGICO dt

        WHERE pp.id_projeto = dt.id_projeto);

 

É correto afirmar que seu objetivo é apresentar o código e o título dos projetos armazenados na tabela

  1. ADESENVOLVIMENTO_TECNOLOGICO que se não se relacionam à tabela PROJETO_PESQUISA.
  2. BDESENVOLVIMENTO_TECNOLOGICO que se relacionam ou não à tabela PROJETO_PESQUISA.
  3. CPROJETO_PESQUISA que estão ou não relacionados a tuplas da tabela DESENVOLVIMENTO_TECNOLOGICO.
  4. DPROJETO_PESQUISA que não estão relacionados a nenhuma tupla da tabela DESENVOLVIMENTO_TECNOLOGICO.
  5. EPROJETO_PESQUISA relacionados a projetos que possuem ocorrências na tabela DESENVOLVIMENTO_TECNOLOGICO.
Revelar gabarito e comentário

GabaritoD — PROJETO_PESQUISA que não estão relacionados a nenhuma tupla da tabela DESENVOLVIMENTO_TECNOLOGICO.

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”.

Consulta SQL com NOT EXISTS: subconsulta correlacionada

Gabarito: letra D. A consulta SELECT cod_projeto, titulo FROM PROJETO_PESQUISA pp WHERE NOT EXISTS (SELECT id_desenvolvimento FROM DESENVOLVIMENTO_TECNOLOGICO dt WHERE pp.id_projeto = dt.id_projeto) retorna os projetos de pesquisa que não possuem nenhum registro associado na tabela DESENVOLVIMENTO_TECNOLOGICO. O NOT EXISTS filtra as linhas da tabela externa (PROJETO_PESQUISA) para as quais a subconsulta correlacionada não retorna nenhuma linha — ou seja, projetos sem nenhum desenvolvimento tecnológico vinculado.

O comando NOT EXISTS é um operador de subconsulta correlacionada no SQL. Para cada linha da consulta externa (a tabela PROJETO_PESQUISA, alias pp), o banco executa a subconsulta interna, que verifica se existe alguma linha na tabela DESENVOLVIMENTO_TECNOLOGICO (alias dt) com o mesmo ID_PROJETO. A correlação acontece na cláusula WHERE pp.id_projeto = dt.id_projeto: o valor de pp.id_projeto é passado de fora para dentro da subconsulta, linha a linha.

O NOT EXISTS inverte o resultado: a linha da tabela externa só é incluída no resultado final se a subconsulta não retornar nenhuma linha. Em outras palavras, o NOT EXISTS seleciona as linhas da tabela externa que não têm correspondência na tabela interna. É o equivalente lógico de um anti-join — o oposto do INNER JOIN, que retorna apenas as linhas com correspondência.

No contexto do enunciado, temos 10 projetos de pesquisa e 24 desenvolvimentos tecnológicos. Apenas um projeto não está associado a nenhum desenvolvimento, e duas tuplas de desenvolvimento não estão associadas a nenhum projeto (o que é possível porque a chave estrangeira ID_PROJETO na tabela DESENVOLVIMENTO_TECNOLOGICO aceita valores nulos, já que não tem a restrição NOT NULL). A consulta retornará exatamente 1 linha: o código e o título do único projeto sem desenvolvimento associado.

A pegadinha da questão está em confundir o NOT EXISTS com o EXISTS (que retornaria os projetos com desenvolvimento associado) ou com um JOIN (que combinaria as duas tabelas). O NOT EXISTS é a forma canônica de encontrar registros órfãos — linhas de uma tabela que não têm correspondência na outra. É uma das consultas mais cobradas em provas de banco de dados, junto com o LEFT JOIN ... WHERE ... IS NULL, que produz o mesmo resultado.

Guarde a fronteira: EXISTS = tem correspondência; NOT EXISTS = não tem correspondência. É exatamente nessa inversão que as alternativas se dividem.

Alternativa A — ❌ Incorreta

Afirma que a consulta retorna dados da tabela DESENVOLVIMENTO_TECNOLOGICO. A consulta seleciona cod_projeto e titulo, que são colunas da tabela PROJETO_PESQUISA (a tabela externa do FROM). A tabela DESENVOLVIMENTO_TECNOLOGICO aparece apenas na subconsulta, e nenhuma de suas colunas é projetada no SELECT final. Além disso, o NOT EXISTS filtra projetos sem desenvolvimento, não desenvolvimentos sem projeto.

Alternativa B — ❌ Incorreta

Afirma que a consulta retorna desenvolvimentos tecnológicos que se relacionam ou não com projetos. Além de errar a tabela de origem (a consulta retorna projetos, não desenvolvimentos), o NOT EXISTS não retorna "todos" os registros — ele filtra apenas aqueles sem correspondência. A alternativa descreveria um SELECT * FROM DESENVOLVIMENTO_TECNOLOGICO sem filtro, não a consulta dada.

Alternativa C — ❌ Incorreta

Afirma que a consulta retorna projetos que estão ou não relacionados a desenvolvimentos. O NOT EXISTS não retorna "todos" os projetos — ele retorna apenas os que não estão relacionados. A alternativa descreveria um SELECT cod_projeto, titulo FROM PROJETO_PESQUISA sem cláusula WHERE, que retornaria todos os 10 projetos. A palavra "ou não" torna a alternativa incorreta: o filtro é restritivo, não inclusivo.

Alternativa D — ✅ Correta ⟵ GABARITO

A consulta retorna exatamente os projetos de pesquisa que não estão relacionados a nenhuma tupla da tabela DESENVOLVIMENTO_TECNOLOGICO. O NOT EXISTS com a subconsulta correlacionada WHERE pp.id_projeto = dt.id_projeto seleciona apenas as linhas de PROJETO_PESQUISA para as quais não existe nenhum desenvolvimento com o mesmo ID_PROJETO. No cenário do enunciado, retorna 1 linha — o único projeto sem desenvolvimento associado.

Alternativa E — ❌ Incorreta

Afirma que a consulta retorna projetos que possuem ocorrências na tabela DESENVOLVIMENTO_TECNOLOGICO. Isso é exatamente o oposto: o NOT EXISTS retorna projetos sem ocorrências. A alternativa descreveria o comportamento do EXISTS (ou de um INNER JOIN), não do NOT EXISTS. É a pegadinha clássica de inverter o operador.

NÃO CAIA NESSA!

A banca explora a inversão do operador NOT EXISTS com EXISTS. A alternativa E descreve o comportamento do EXISTS (projetos com desenvolvimento), enquanto a consulta pede o NOT EXISTS (projetos sem desenvolvimento). Na prova, sublinhe o NOT e pergunte: "a consulta quer os que têm ou os que não têm?" — isso resolve a questão em segundos.

PEGA ESSA DICA!

Para questões de NOT EXISTS, traduza mentalmente: "selecione as linhas da tabela externa para as quais a subconsulta não retorna nada". Compare com o LEFT JOIN ... WHERE ... IS NULL, que produz o mesmo resultado. Se a alternativa disser "que estão ou não", "todos", ou "que possuem", desconfie — o NOT EXISTS é sempre restritivo e seletivo.

Gabarito: letra D

Link permanente: /questoes/fg157162