Pular para o conteúdo principal

Questão de Banco de Dados — SQL — FUNDATEC 2025

Banco de DadosSQL
Código
qg472043
Banca
FUNDATEC
Órgão
GHC-RS
Ano
2025
Nível
Médio
Cargo
Programador
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:


Imagem da questão
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.
  1. Aselect nivel.niv_nome, count(*) total FROM funcionarioinner join cargo on funcionario.car_id = nivel.niv_idwhere cargo.niv_id= 1group by cargo.niv_id
  2. Bselect nivel.niv_nome, count(*) total FROM funcionarioinner join cargo on funcionario.car_id = nivel.niv_idgroup by cargo.niv_idhaving cargo.niv_id= 1
  3. Cselect nivel.niv_nome, count(*) total FROM funcionarioinner join cargo on funcionario.car_id = cargo.car_idinner join nivel on cargo.niv_id = nivel.niv_idhaving cargo.niv_id= 1group by cargo.niv_id
  4. Dselect nivel.niv_nome, count(*) total FROM funcionarioinner join cargo on funcionario.car_id = cargo.car_idinner join nivel on cargo.niv_id = nivel.niv_idgroup by cargo.niv_idhaving cargo.niv_id= 1
  5. Eselect nivel.niv_nome, count(*) total FROM funcionarioinner join cargo on funcionario.car_id = cargo.car_idinner join nivel on cargo.niv_id = nivel.niv_idgroup by cargo.niv_idwhere 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”.

SQL: GROUP BY, HAVING e WHERE em consultas agregadas

Gabarito: letra D. A consulta correta deve unir as três tabelas (funcionario, cargo e nivel), agrupar por cargo.niv_id e filtrar o grupo com HAVING cargo.niv_id = 1 — porque o filtro incide sobre o resultado da agregação, não sobre linhas individuais. A alternativa D é a única que combina os três JOINs corretos, o GROUP BY e o HAVING na ordem certa.

O que a questão cobra

A questão testa o domínio de três cláusulas do SQL que aparecem juntas em consultas com agregação: WHERE, GROUP BY e HAVING. Entender a diferença entre WHERE e HAVING é o coração da questão.

  • WHERE filtra linhas antes da agregação. Ele não pode usar funções de agregação (COUNT, SUM, AVG etc.) porque essas funções ainda não foram calculadas quando o WHERE é avaliado.

  • GROUP BY agrupa as linhas que têm o mesmo valor nas colunas indicadas, formando grupos. Para cada grupo, as funções de agregação são aplicadas.

  • HAVING filtra grupos depois da agregação. Ele pode usar funções de agregação, pois é avaliado após o GROUP BY.

A ordem lógica de execução de uma consulta SQL é:

  1. FROM (e JOINs)

  2. WHERE

  3. GROUP BY

  4. HAVING

  5. SELECT

  6. ORDER BY

Isso explica por que o WHERE não pode filtrar por COUNT(*) (a agregação ainda não ocorreu) e por que o HAVING não pode filtrar linhas individuais (as linhas já foram agrupadas).

A estrutura do banco

Pelo modelo ER e pelo dicionário de dados, temos:

  • funcionario: contém car_id (chave estrangeira para cargo).

  • cargo: contém car_id (chave primária) e niv_id (chave estrangeira para nivel).

  • nivel: contém niv_id (chave primária) e niv_nome (nome do nível).

Para apresentar a quantidade de funcionários por nível de cargo, precisamos:

  1. Unir funcionario com cargo (via car_id).

  2. Unir cargo com nivel (via niv_id).

  3. Agrupar por cargo.niv_id (ou nivel.niv_id).

  4. Selecionar nivel.niv_nome e COUNT(*).

  5. Filtrar apenas o nível com niv_id = 1.

Análise das alternativas

Critério

Alternativa D (gabarito)

Alternativa E (quase correta)

JOINs

funcionario.car_id = cargo.car_id e cargo.niv_id = nivel.niv_id (corretos)

Mesmos JOINs corretos

Filtro

HAVING cargo.niv_id = 1 (filtra o grupo após agregação)

WHERE cargo.niv_id = 1 (filtra linhas antes da agregação)

Ordem das cláusulas

FROM → JOINs → GROUP BY → HAVING (correta)

FROM → JOINs → WHERE → GROUP BY (correta, mas usa WHERE)

Resultado

Retorna apenas o grupo com niv_id = 1

Retorna apenas linhas com niv_id = 1, depois agrupa

Adequação ao enunciado

✅ Filtra o grupo conforme pedido

⚠️ Funciona tecnicamente, mas não usa HAVING como esperado

Alternativa A — ❌ Incorreta

O JOIN está errado: funcionario.car_id = nivel.niv_id compara colunas de tabelas diferentes sem relação direta. O correto seria funcionario.car_id = cargo.car_id e depois cargo.niv_id = nivel.niv_id. Além disso, falta o JOIN com a tabela nivel, então a coluna nivel.niv_nome não estaria disponível. O WHERE está correto, mas a consulta não funcionaria por causa do JOIN incorreto.

Alternativa B — ❌ Incorreta

O JOIN está errado (mesmo problema da alternativa A: funcionario.car_id = nivel.niv_id). Além disso, falta o JOIN com nivel, então nivel.niv_nome não pode ser selecionado. O HAVING está correto, mas sem o JOIN adequado a consulta falha.

Alternativa C — ❌ Incorreta

Os JOINs estão corretos, mas a ordem das cláusulas está errada: o HAVING vem antes do GROUP BY. A ordem correta é GROUP BY antes de HAVING. Além disso, o HAVING filtra grupos, mas aqui ele é usado sem o GROUP BY ter sido executado, o que gera erro de sintaxe ou comportamento incorreto.

Alternativa D — ✅ Correta ⟵ GABARITO

Esta alternativa tem:

  • JOINs corretos: funcionario.car_id = cargo.car_id e cargo.niv_id = nivel.niv_id.

  • GROUP BY cargo.niv_id (agrupa por nível).

  • HAVING cargo.niv_id = 1 (filtra o grupo do nível 1).

  • SELECT nivel.niv_nome e COUNT(*).

A ordem está correta: FROM → JOINs → GROUP BY → HAVING. O HAVING é usado para filtrar o grupo, que é exatamente o que a questão pede.

Alternativa E — ❌ Incorreta

Os JOINs estão corretos, mas o filtro cargo.niv_id = 1 está no WHERE, não no HAVING. Embora o WHERE também filtre por niv_id = 1, a questão pede explicitamente "filtrando pela identificação do nível do cargo igual a 1" — e a alternativa D usa HAVING, que é a forma correta quando se filtra após agregação. Tecnicamente, o WHERE também funcionaria, mas a banca considera o HAVING como a resposta correta, pois o filtro é sobre o grupo. Além disso, a alternativa E não tem HAVING, o que a torna incompleta para o que a questão pede.

Conclusão

A alternativa D é a única que apresenta a sintaxe correta: JOINs adequados, GROUP BY e HAVING na ordem certa, filtrando o grupo com niv_id = 1.

Gabarito: letra D

Link permanente: /questoes/qg472043