Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FUNDATEC 2023

Banco de DadosConsultas e Comandos em SQL
Código
qa537872
Banca
FUNDATEC
Órgão
PROCERGS
Ano
2023
Cargo
ANC ( )

Imagem associada para resolução da questão

 

Considerando o modelo ER apresentado pela Figura 1, pretende-se implementar uma expressão SQL para apresentar o nome de todos os empregados (emp_nome), a descrição APENAS do último cargo (car_descricao) que cada um assumiu, bem como a data de início (emc_inicio) nesse último cargo. Sendo assim, analise as assertivas abaixo.

 

I.

select emp_nome, (select car_descricao

from empregadocargo ec, cargo c

where ec.car_id = c.car_id

and sub.emp_id = emp_id

and sub.emc_inicio = emc_inicio) car_descricao, emc_inicio

from (select emp_id, max(emc_inicio) emc_inicio

from empregadocargo

group by emp_id) sub

b inner join empregado e on e.emp_id = sub.emp_id;

 

II.

select emp_nome, car_descricao, max(emc_inicio) emc_inicio

from empregadocargo ec

inner join empregado e on ec.emp_id = e.emp_id

inner join cargo c on ec.car_id = c.car_id

group by emp_nome;

 

III.

select distinct emp_nome, car_descricao,

(select max(emc_inicio) from empregadocargo

where emp_id = e.emp_id and car_id = c.car_id) emc_inicio

from empregadocargo ec

inner join empregado e on ec.emp_id = e.emp_id

inner join cargo c on ec.car_id = c.car_id

group by emp_nome;

 

Quais estão corretas?

  1. AApenas I.
  2. BApenas I e II.
  3. CApenas I e III.
  4. DApenas II e III.
  5. EI, II e III.
Revelar gabarito e comentário

GabaritoA — Apenas I.

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: último cargo de cada empregado

Gabarito: letra A. Apenas a assertiva I está correta. A consulta I usa uma subconsulta correlacionada para obter a descrição do cargo cuja data de início é a máxima para cada empregado, garantindo que apenas o último cargo seja retornado. As assertivas II e III estão incorretas porque não conseguem isolar corretamente o último cargo de cada empregado, retornando dados incorretos ou duplicados.

O problema central desta questão é a necessidade de, para cada empregado, identificar o registro de empregadocargo com a maior data de início (emc_inicio) e, a partir desse registro, obter a descrição do cargo correspondente. Isso é um clássico problema de "máximo por grupo" em SQL, que pode ser resolvido de várias formas, mas exige cuidado para não retornar cargos antigos ou duplicar informações.

A abordagem mais direta é usar uma subconsulta na cláusula FROM para calcular, para cada emp_id, o valor máximo de emc_inicio. Essa subconsulta cria uma tabela derivada (aliased como sub) com duas colunas: emp_id e emc_inicio (a data máxima). Em seguida, essa tabela derivada é unida à tabela empregadocargo (para obter o car_id correspondente à data máxima) e à tabela empregado (para obter o emp_nome). A subconsulta correlacionada na cláusula SELECT então busca a car_descricao do cargo cujo car_id e emc_inicio correspondem aos valores da linha atual da tabela derivada. Essa é a lógica da assertiva I.

A assertiva II tenta resolver o problema usando GROUP BY emp_nome e MAX(emc_inicio), mas isso é incorreto porque, ao agrupar por emp_nome, a consulta retorna uma linha por empregado, mas a coluna car_descricao não é agregada nem incluída no GROUP BY. Em SQL padrão, isso é um erro de sintaxe (coluna não agregada e não agrupada). Mesmo que o SGBD permitisse (como o MySQL com ONLY_FULL_GROUP_BY desabilitado), o resultado seria imprevisível: a car_descricao retornada não seria necessariamente a do cargo com a data máxima, pois o SGBD escolheria um valor arbitrário do grupo.

A assertiva III usa SELECT DISTINCT e uma subconsulta correlacionada para calcular MAX(emc_inicio) para cada combinação de emp_id e car_id. No entanto, isso não resolve o problema, pois a subconsulta retorna a data máxima para cada cargo individual, não para o empregado como um todo. O resultado incluiria todos os cargos que o empregado já ocupou, cada um com sua própria data máxima, e não apenas o último cargo. Além disso, a cláusula GROUP BY emp_nome é desnecessária e potencialmente conflitante com o SELECT DISTINCT, e a subconsulta correlacionada não está corretamente vinculada à linha externa.

Para entender melhor, considere um exemplo: um empregado com emp_id = 1 ocupou o cargo A (início em 2020) e o cargo B (início em 2022). A assertiva I retornaria apenas o cargo B (o último). A assertiva II retornaria uma linha com emp_nome, car_descricao (arbitrária) e MAX(emc_inicio) = 2022. A assertiva III retornaria duas linhas: uma para o cargo A com data 2020 e outra para o cargo B com data 2022, pois a subconsulta calcula o máximo por cargo, não por empregado.

A pegadinha desta questão está em reconhecer que GROUP BY sozinho não resolve o problema de "último registro por grupo" quando se precisa de outras colunas do registro que contém o máximo. A banca explora a confusão entre agregação simples e a necessidade de uma subconsulta ou junção para obter o registro completo associado ao valor máximo.

Assertiva

Correção

Motivo

I

✅ Correta

Usa subconsulta na cláusula FROM para calcular MAX(emc_inicio) por empregado e subconsulta correlacionada no SELECT para obter a car_descricao do cargo com a data máxima, retornando exatamente o último cargo de cada empregado.

II

❌ Incorreta

GROUP BY emp_nome sem agregar car_descricao gera erro de sintaxe em SQL padrão; mesmo se permitido, a descrição retornada seria arbitrária, não necessariamente a do cargo com a data máxima.

III

❌ Incorreta

A subconsulta correlacionada calcula MAX(emc_inicio) por combinação de emp_id e car_id, retornando todos os cargos do empregado (cada um com sua data máxima), e não apenas o último; além disso, a subconsulta referencia tabelas não vinculadas corretamente.

Assertiva I — ✅ Correta

A consulta I está correta. Ela usa uma subconsulta na cláusula FROM para calcular, para cada emp_id, o valor máximo de emc_inicio. Essa subconsulta é aliased como sub e contém emp_id e emc_inicio. Em seguida, a consulta principal faz um INNER JOIN entre sub e empregado (para obter emp_nome) e usa uma subconsulta correlacionada na cláusula SELECT para obter a car_descricao do cargo cujo car_id e emc_inicio correspondem aos valores da linha atual de sub. A subconsulta correlacionada referencia sub.emp_id e sub.emc_inicio, garantindo que apenas o cargo com a data máxima seja retornado. A consulta também seleciona emc_inicio diretamente da tabela derivada sub, que contém a data máxima. Portanto, a consulta retorna o nome do empregado, a descrição do último cargo e a data de início desse cargo, exatamente como pedido.

Assertiva II — ❌ Incorreta

A assertiva II está incorreta. A consulta usa GROUP BY emp_nome e seleciona car_descricao sem agregá-la. Em SQL padrão, isso é um erro de sintaxe, pois car_descricao não está no GROUP BY nem é usada em uma função de agregação. Mesmo que o SGBD permitisse (com ONLY_FULL_GROUP_BY desabilitado), o resultado seria incorreto: a car_descricao retornada seria arbitrária, não necessariamente a do cargo com a data máxima. Além disso, a consulta retorna MAX(emc_inicio), mas não há garantia de que a car_descricao corresponda a esse máximo. O GROUP BY emp_nome agrupa todas as linhas de um empregado, mas não seleciona o registro específico com a maior data.

Assertiva III — ❌ Incorreta

A assertiva III está incorreta. A consulta usa SELECT DISTINCT e uma subconsulta correlacionada para calcular MAX(emc_inicio) para cada combinação de emp_id e car_id. No entanto, isso retorna a data máxima para cada cargo individual, não para o empregado como um todo. O resultado incluiria todos os cargos que o empregado já ocupou, cada um com sua própria data máxima, e não apenas o último cargo. Além disso, a cláusula GROUP BY emp_nome é desnecessária e potencialmente conflitante com o SELECT DISTINCT, e a subconsulta correlacionada não está corretamente vinculada à linha externa, pois referencia e.emp_id e c.car_id, mas a tabela ec não é usada na subconsulta. A consulta não isola o último cargo de cada empregado.

Gabarito: letra A — apenas a assertiva I está correta.

Link permanente: /questoes/qa537872