Questão de Banco de Dados — Consultas e Comandos em SQL — FUNDATEC 2025
Banco de Dados›Consultas e Comandos em SQL
Código
qa699084
Banca
FUNDATEC
Órgão
GHC
Ano
2025
Cargo
Prog ( )
Para responder à questão, considere o modelo Entidade-Relacionamento (ER) apresentado pela Figura 1 abaixo, bem como o dicionário de dados apresentado logo em seguida:
Figura 1 – Modelo Entidade-Relacionamento (ER)
Dicionário de dados
Qual alternativa contém a instrução SQL correta para apresentar a quantidade de funcionários por nível de cargo? A consulta deve apresentar o(s) nome(s) do nível do cargo e a respectiva quantidade de funcionários, filtrando pela identificação do nível do cargo igual a 1.
Aselect nivel.niv_nome, count(*) total FROM funcionario inner join cargo on funcionario.car_id = nivel.niv_id where cargo.niv_id= 1 group by cargo.niv_id
Bselect nivel.niv_nome, count(*) total FROM funcionario inner join cargo on funcionario.car_id = nivel.niv_id group by cargo.niv_id having cargo.niv_id= 1
Cselect nivel.niv_nome, count(*) total FROM funcionario inner join cargo on funcionario.car_id = cargo.car_id inner join nivel on cargo.niv_id = nivel.niv_id having cargo.niv_id= 1 group by cargo.niv_id
Dselect nivel.niv_nome, count(*) total FROM funcionario inner join cargo on funcionario.car_id = cargo.car_id inner join nivel on cargo.niv_id = nivel.niv_id group by cargo.niv_id having cargo.niv_id= 1
Eselect nivel.niv_nome, count(*) total FROM funcionario inner join cargo on funcionario.car_id = cargo.car_id inner join nivel on cargo.niv_id = nivel.niv_id group by cargo.niv_id where cargo.niv_id= 1
Revelar gabarito e comentário▾
GabaritoD — select nivel.niv_nome, count(*) total FROM funcionario
inner join cargo on funcionario.car_id = cargo.car_id
inner join nivel on cargo.niv_id = nivel.niv_id
group by cargo.niv_id
having cargo.niv_id= 1
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 JOIN, GROUP BY e HAVING
Gabarito: letra D. A consulta correta deve unir as tabelas funcionario, cargo e nivel pelos relacionamentos corretos, agrupar por cargo.niv_id e filtrar o grupo com HAVING cargo.niv_id = 1. A alternativa D é a única que combina os três JOINs corretos, o GROUP BY e o HAVING na ordem certa.
A ideia por trás
A questão pede uma consulta que apresente a quantidade de funcionários por nível de cargo, filtrando pelo nível de identificação igual a 1. Para isso, precisamos entender o papel de cada cláusula SQL:
FROM: define as tabelas de origem dos dados.
JOIN: combina linhas de duas ou mais tabelas com base em uma condição de relacionamento (chave estrangeira).
WHERE: filtra linhas antes da agregação (antes do GROUP BY).
GROUP BY: agrupa linhas que têm o mesmo valor em uma ou mais colunas, permitindo o uso de funções de agregação como COUNT(*).
HAVING: filtra grupos após a agregação (depois do GROUP BY).
A ordem lógica de execução de uma consulta SQL é: FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. Isso significa que o WHERE filtra linhas individuais antes de agrupar, enquanto o HAVING filtra os grupos já formados.
No caso, queremos filtrar por cargo.niv_id = 1. Como queremos contar funcionários por nível, e o filtro é sobre uma coluna que também está no GROUP BY, tanto o WHERE quanto o HAVING poderiam funcionar. Porém, a alternativa correta usa HAVING, que é válido e atende ao requisito.
Analisando as alternativas
Critério
Alternativa D (correta)
Alternativas A/B
Alternativa C
Alternativa E
JOINs
3 JOINs corretos (funcionario→cargo→nivel)
JOIN errado (funcionario.car_id = nivel.niv_id) e falta JOIN com nivel
3 JOINs corretos
3 JOINs corretos
Ordem das cláusulas
FROM → JOIN → GROUP BY → HAVING (correta)
FROM → JOIN → WHERE → GROUP BY (A) ou FROM → JOIN → GROUP BY → HAVING (B)
HAVING antes do GROUP BY (errada)
WHERE depois do GROUP BY (errada)
Filtro
HAVING cargo.niv_id = 1 (após agregação)
WHERE (A) ou HAVING (B)
HAVING (mas em posição errada)
WHERE (mas em posição errada)
Acesso a niv_nome
Sim (via JOIN com nivel)
Não (falta JOIN com nivel)
Sim
Sim
Sintaxe válida
✅ Válida
❌ Inválida (JOIN incorreto)
❌ Inválida (ordem errada)
❌ Inválida (ordem errada)
Alternativa A — ❌ Incorreta
O erro está no JOIN: inner join cargo on funcionario.car_id = nivel.niv_id. A condição de junção está errada, pois relaciona funcionario.car_id com nivel.niv_id, quando deveria relacionar funcionario.car_id com cargo.car_id. Além disso, falta o JOIN com a tabela nivel, necessária para exibir nivel.niv_nome. A consulta não retornaria os nomes dos níveis corretamente.
Alternativa B — ❌ Incorreta
O JOIN está errado: inner join cargo on funcionario.car_id = nivel.niv_id. Novamente, relaciona funcionario.car_id com nivel.niv_id, em vez de cargo.car_id. Também falta o JOIN com a tabela nivel, essencial para obter nivel.niv_nome. Sem esse JOIN, a consulta não tem acesso à coluna niv_nome.
Alternativa C — ❌ Incorreta
A ordem das cláusulas está errada: having cargo.niv_id= 1 aparece antes do group by cargo.niv_id. A sintaxe correta exige que o GROUP BY venha antes do HAVING. Essa inversão causa erro de sintaxe na maioria dos SGBDs.
Alternativa D — ✅ Correta ⟵ GABARITO
A consulta faz os três JOINs corretamente: funcionario com cargo (via car_id) e cargo com nivel (via niv_id). Depois, agrupa por cargo.niv_id e filtra o grupo com HAVING cargo.niv_id = 1. A ordem das cláusulas está correta: FROM → JOIN → GROUP BY → HAVING. Isso retorna o nome do nível e a quantidade de funcionários para o nível 1.
Alternativa E — ❌ Incorreta
A ordem das cláusulas está errada: where cargo.niv_id= 1 aparece depois do group by cargo.niv_id. A sintaxe correta exige que o WHERE venha antes do GROUP BY. Essa inversão causa erro de sintaxe.
Conclusão
A alternativa D é a única que apresenta a sintaxe correta, com os JOINs adequados, o GROUP BY e o HAVING na ordem certa. As demais alternativas erram na condição de junção, na ordem das cláusulas ou na falta de JOIN com a tabela nivel.