Pular para o conteúdo principal

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

Banco de DadosConsultas e Comandos em SQL
Código
fg169074
Banca
FGV
Órgão
DPE RO
Ano
2025
Cargo
TDP ( )

Seja o seguinte esquema relacional de banco de dados: tb_processos(id_processo, numero_processo, tipo, status, data_abertura)

 

Restrições:

 

id_processo é chave primária

numero_processo não pode ser nulo

tipo pode assumir os valores {"Ação de Alimentos", "Defesa Criminal"}.

status pode assumir os valores {"Em andamento", "Arquivado", "Sentenciado"}

 

tb_movimentacoes(id_movimentacao, descricao,

data_movimentacao, id_processo<FK>)

 

Restrições:

 

id_movimentacao é chave primária

descricao não pode ser nulo

descricao pode assumir os valores { "Petição inicial protocolada", "Audiência realizada"}.

id_processo é chave estrangeira e referencia a tabela tb_processos

 

Submeteu-se ao sistema que gerencia esse banco de dados relacional a consulta:

 

select mov.descricao, mov.data_movimentacao

from tb_movimentacoes mov

where exists

( select proc.id_processo from tb_processos proc

where proc.id_processo=mov.id_processo

and proc.status='Arquivado' )

 

O otimizador de consultas do sistema, ao avaliar a consulta, identificou tratar-se de um caso de consulta correlata, com uma subconsulta aninhada referenciando um elemento de dado da consulta externa.

 

Considerando que o otimizador decidiu e é capaz de implementar a melhor opção de otimização, qual das opções apresenta uma consulta equivalente à anteriormente proposta, após a aplicação da técnica de desalinhamento?

  1. Aselect mov.descricao, mov.data_movimentacao from tb_movimentacoes mov where mov.id_processo in (select proc.id_processo from tb_processos proc where proc.status='Arquivado')
  2. Bselect mov.descricao, mov.data_movimentacao from tb_movimentacoes mov left join tb_processos proc on proc.id_processo=mov.id_processo where proc.status='Arquivado'
  3. Cselect mov.descricao, mov.data_movimentacao from tb_movimentacoes mov natural join tb_processos proc where proc.status='Arquivado'
  4. Dselect mov.descricao, mov.data_movimentacao from tb_movimentacoes mov where mov.id_processo any (select proc.id_processo from tb_processos proc where proc.status='Arquivado')
  5. Eselect mov.descricao, mov.data_movimentacao from tb_movimentacoes mov union select proc.id_processo from tb_processos proc where proc.status='Arquivado'
Revelar gabarito e comentário

GabaritoC — select mov.descricao, mov.data_movimentacao from tb_movimentacoes mov natural join tb_processos proc where proc.status='Arquivado'

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

Desalinhamento de Subconsultas Correlatas em SQL

Gabarito: letra C. A técnica de desalinhamento (ou unnesting) transforma a subconsulta correlata em uma junção equivalente, e a opção que implementa corretamente essa transformação é a que usa natural join entre tb_movimentacoes e tb_processos, filtrando proc.status='Arquivado'. A consulta original retorna as movimentações cujo processo associado está arquivado — exatamente o que a junção natural entre as duas tabelas, seguida do filtro de status, produz.

A consulta original é um exemplo clássico de subconsulta correlata: a subconsulta interna referencia a consulta externa através da condição proc.id_processo = mov.id_processo. Para cada linha de tb_movimentacoes, o SGBD executa a subconsulta, verificando se existe um processo com aquele id_processo e com status = 'Arquivado'. O operador EXISTS retorna verdadeiro se a subconsulta retornar pelo menos uma linha, e falso caso contrário.

O desalinhamento (ou unnesting) é uma otimização que elimina a correlação, transformando a subconsulta em uma operação de junção. A ideia é que, em vez de executar a subconsulta para cada linha da tabela externa, o otimizador pode combinar as duas tabelas de uma vez e depois aplicar o filtro. A junção natural (NATURAL JOIN) é a forma mais direta: ela combina as linhas das duas tabelas onde os valores das colunas com o mesmo nome são iguais — aqui, id_processo — e o resultado é filtrado por status = 'Arquivado'. Isso produz exatamente o mesmo conjunto de movimentações que a consulta original.

Vamos ver por que as outras opções falham:

  • A) Usa IN com uma subconsulta não correlata. Embora semanticamente equivalente em muitos casos, a subconsulta não é correlata e a transformação não é um desalinhamento típico — além disso, a opção não usa junção, que é a técnica de desalinhamento mencionada.

  • B) Usa LEFT JOIN, que preserva todas as linhas de tb_movimentacoes, mesmo aquelas sem processo correspondente. O filtro proc.status='Arquivado' no WHERE elimina as linhas sem correspondência (porque proc.status seria NULL), mas a semântica de LEFT JOIN não é a mais adequada para representar a equivalência com EXISTS — um INNER JOIN seria mais natural.

  • D) A sintaxe mov.id_processo any (...) está incorreta — o correto seria = ANY (...), e mesmo assim não é a forma de desalinhamento por junção.

  • E) Usa UNION, que combina resultados de duas consultas, mas não representa a interseção lógica exigida — além de tentar unir colunas diferentes (descricao, data_movimentacao com id_processo), o que é semanticamente inválido.

A pegadinha aqui é que a banca testa se o candidato conhece a técnica de desalinhamento e consegue identificar a junção equivalente. Muitos candidatos podem marcar a opção A, que usa IN, mas a questão pede especificamente a técnica de desalinhamento, que é a transformação em junção.

1Subconsulta correlata
Referencia consulta externa
EXISTS por linha
2Transformação
Junção equivalente
Filtro após juntar
3Formas corretas
NATURAL JOIN
INNER JOIN
4Formas incorretas
LEFT JOIN (preserva sem correspondência)
UNION (união, não interseção)
IN (não é junção)
Desalinhamento (unnesting)
LEVELsoulevel.com.br
Desalinhamento (unnesting): Subconsulta correlata (Referencia consulta externa, EXISTS por linha); Transformação (Junção equivalente, Filtro após juntar); Formas corretas (NATURAL JOIN, INNER JOIN); Formas incorretas (LEFT JOIN (preserva sem correspondência), UNION (união, não interseção), IN (não é junção))

Alternativa A — ❌ Incorreta

A opção A usa IN com uma subconsulta não correlata. Embora semanticamente equivalente à consulta original (retorna as movimentações cujo id_processo está na lista de processos arquivados), ela não representa a técnica de desalinhamento por junção. O desalinhamento transforma a subconsulta correlata em uma operação de junção, não em outra subconsulta. Além disso, a subconsulta aqui não é correlata, pois não referencia a consulta externa.

Alternativa B — ❌ Incorreta

A opção B usa LEFT JOIN, que preserva todas as linhas de tb_movimentacoes, mesmo aquelas sem processo correspondente. O filtro proc.status='Arquivado' no WHERE elimina as linhas sem correspondência (porque proc.status seria NULL), mas a semântica de LEFT JOIN não é a mais adequada para representar a equivalência com EXISTS — um INNER JOIN seria mais natural. A junção natural (opção C) é a forma correta de desalinhamento.

Alternativa C — ✅ Correta ⟵ GABARITO

A opção C usa NATURAL JOIN, que combina as linhas das duas tabelas onde os valores das colunas com o mesmo nome são iguais — aqui, id_processo. O filtro proc.status='Arquivado' seleciona apenas as movimentações cujo processo está arquivado. Isso é exatamente o que a consulta original com EXISTS faz: retorna as movimentações para as quais existe um processo arquivado com o mesmo id_processo. A junção natural é a forma clássica de desalinhamento de subconsultas correlatas.

Alternativa D — ❌ Incorreta

A opção D usa a sintaxe mov.id_processo any (...), que está incorreta. O operador correto seria = ANY (...), e mesmo assim não é a forma de desalinhamento por junção. A sintaxe ANY é usada para comparar um valor com qualquer elemento de uma lista, mas não é a técnica de desalinhamento mencionada na questão.

Alternativa E — ❌ Incorreta

A opção E usa UNION, que combina os resultados de duas consultas. No entanto, a consulta original é uma interseção lógica (movimentações cujo processo está arquivado), não uma união. Além disso, a segunda consulta seleciona proc.id_processo, que não é compatível com as colunas descricao e data_movimentacao da primeira — a operação UNION exige que as colunas correspondam em número e tipo. Portanto, a opção E é semanticamente inválida.

PEGA ESSA DICA!

Para identificar a técnica de desalinhamento, procure pela transformação da subconsulta correlata em uma junção. A junção natural (NATURAL JOIN) ou INNER JOIN com condição explícita são as formas mais comuns. Lembre-se: EXISTS com correlação equivale a uma junção interna com filtro, não a LEFT JOIN ou UNION.

Gabarito: letra C

Link permanente: /questoes/fg169074