Pular para o conteúdo principal

Questão de Banco de Dados — Banco de Dados Relacionais — UNIDAVI 2026

Banco de DadosBanco de Dados Relacionais
Código
qg764195
Banca
UNIDAVI
Órgão
Prefeitura de Agrolândia - SC
Ano
2026
Nível
Superior
Cargo
Analista de Informática
Um órgão público mantém um banco de dados relacional para controle de contratos administrativos, estruturado nas seguintes tabelas simplificadas: SERVIDOR (id_servidor, nome, lotacao), CONTRATO (id_contrato, id_servidor, valor, data_inicio, data_fim) e PAGAMENTO (id_pagamento, id_contrato, valor_pago, data_pagamento). Cada contrato vincula-se a um único servidor e pode registrar múltiplos pagamentos. Deseja-se identificar os servidores cuja soma dos valores pagos no ano de 2025 ultrapassou R$ 100.000,00, considerando apenas contratos que permaneçam vigentes em 31/12/2025. A consulta deve retornar o nome do servidor e o total pago no período, sem incluir servidores que não tenham recebido pagamentos em 2025. Assinale a alternativa CORRETA que atende adequadamente ao enunciado:
  1. ASELECT DISTINCT s.nome, SUM(p.valor_pago)FROM servidor sJOIN contrato c ON s.id_servidor = c.id_servidorJOIN pagamento p ON p.id_pagamento =c.id_contratoWHERE p.data_pagamento > = '2025-01-01'GROUP BY s.nomeORDER BY SUM(p.valor_pago) DESC;
  2. BSELECT nome, SUM(valor_pago)FROM servidor, contrato, pagamentoWHERE servidor.id_servidor = contrato.id_contratoAND contrato.id_contrato = pagamento.id_pagamentoAND YEAR(data_pagamento) = 2025GROUP BY nome
  3. CSELECT s.nome, SUM(p.valor_pago)FROM servidor s, contrato c, pagamento pWHERE s.id_servidor = c.id_servidorAND c.id_contrato = p.id_contratoAND p.data_pagamento BETWEEN '2024-01-01'AND '2025-12-31'AND c.data_fim > = '2025-12-31'GROUP BY s.nomeHAVING SUM(p.valor_pago) > 100000;
  4. DSELECT s.nome, SUM(p.valor_pago) AS total_pagoFROM servidor sINNER JOIN contrato c ON s.id_servidor = c.id_servidorINNER JOIN pagamento p ON c.id_contrato = p.id_contratoWHERE p.data_pagamento BETWEEN '2025-01-01'AND '2025-12-31'AND c.data_inicio < = '2025-12-31'AND (c.data_fim IS NULL OR c.data_fim >= '2025-12-31')GROUP BY s.nomeHAVING SUM(p.valor_pago) > 100000;
  5. ESELECT s.nome, SUM(p.valor_pago)FROM servidor sLEFT JOIN contrato c ON s.id_servidor = c.id_servidorLEFT JOIN pagamento p ON c.id_contrato = p.id_contratoWHERE p.data_pagamento LIKE '2025%'AND c.data_fim > = '2025-12-31' GROUP BY s.nomeHAVING SUM(p.valor_pago) > = 100000;
Revelar gabarito e comentário

GabaritoD — SELECT s.nome, SUM(p.valor_pago) AS total_pago FROM servidor s INNER JOIN contrato c ON s.id_servidor = c.id_servidor INNER JOIN pagamento p ON c.id_contrato = p.id_contrato WHERE p.data_pagamento BETWEEN '2025-01-01' AND '2025-12-31' AND c.data_inicio < = '2025-12-31' AND (c.data_fim IS NULL OR c.data_fim >= '2025-12-31') GROUP BY s.nome HAVING SUM(p.valor_pago) > 100000;

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 para servidores com total de pagamentos > R$ 100.000 em 2025 (contratos vigentes)

A questão testa a capacidade de escrever uma consulta SQL que atenda a múltiplos requisitos:

  • Soma dos valores pagos no ano de 2025.

  • Apenas contratos vigentes em 31/12/2025 (data_fim >= '2025-12-31' ou nula).

  • Excluir servidores sem pagamentos em 2025 (uso de INNER JOIN).

  • Retornar nome e total pago, agrupado por servidor, com filtro HAVING SUM > 100000.

Vamos analisar cada alternativa.

Alternativa A — ❌ Incorreta

SELECT DISTINCT s.nome, SUM(p.valor_pago)
FROM servidor s
JOIN contrato c ON s.id_servidor = c.id_servidor
JOIN pagamento p ON p.id_pagamento = c.id_contrato
WHERE p.data_pagamento >= '2025-01-01'
GROUP BY s.nome
ORDER BY SUM(p.valor_pago) DESC;

Erros:

  1. A condição de JOIN entre pagamento e contrato está errada: p.id_pagamento = c.id_contrato deveria ser p.id_contrato = c.id_contrato. Isso provavelmente não retornará resultados corretos.

  2. Não há filtro para contratos vigentes em 31/12/2025 (falta c.data_fim >= '2025-12-31').

  3. O WHERE considera pagamentos a partir de 01/01/2025, mas não limita até 31/12/2025 (embora isso seja menos crítico, o ideal é usar BETWEEN ou duas condições).

  4. DISTINCT é desnecessário com GROUP BY.

Alternativa B — ❌ Incorreta

SELECT nome, SUM(valor_pago)
FROM servidor, contrato, pagamento
WHERE servidor.id_servidor = contrato.id_contrato
AND contrato.id_contrato = pagamento.id_pagamento
AND YEAR(data_pagamento) = 2025
GROUP BY nome

Erros:

  1. As condições de junção estão trocadas: servidor.id_servidor = contrato.id_contrato deveria ser servidor.id_servidor = contrato.id_servidor; contrato.id_contrato = pagamento.id_pagamento deveria ser contrato.id_contrato = pagamento.id_contrato.

  2. Não há filtro de contratos vigentes.

  3. Não há HAVING para filtrar soma > 100000.

  4. A função YEAR pode não ser portável (depende do SGBD), mas não é o principal erro.

Alternativa C — ❌ Incorreta

SELECT s.nome, SUM(p.valor_pago)
FROM servidor s, contrato c, pagamento p
WHERE s.id_servidor = c.id_servidor
AND c.id_contrato = p.id_contrato
AND p.data_pagamento BETWEEN '2024-01-01' AND '2025-12-31'
AND c.data_fim >= '2025-12-31'
GROUP BY s.nome
HAVING SUM(p.valor_pago) > 100000;

Erro principal: O filtro de data do pagamento está errado: BETWEEN '2024-01-01' AND '2025-12-31' inclui pagamentos de 2024, o que não atende ao enunciado (apenas 2025). O correto seria BETWEEN '2025-01-01' AND '2025-12-31'. Além disso, não considera contratos com data_fim nula (vigentes por prazo indeterminado). Embora a condição c.data_fim >= '2025-12-31' esteja presente, a falha no filtro de ano invalida a consulta.

Alternativa D — ✅ Correta

SELECT s.nome, SUM(p.valor_pago) AS total_pago
FROM servidor s
INNER JOIN contrato c ON s.id_servidor = c.id_servidor
INNER JOIN pagamento p ON c.id_contrato = p.id_contrato
WHERE p.data_pagamento BETWEEN '2025-01-01' AND '2025-12-31'
AND c.data_inicio <= '2025-12-31'
AND (c.data_fim IS NULL OR c.data_fim >= '2025-12-31')
GROUP BY s.nome
HAVING SUM(p.valor_pago) > 100000;

Por que está correta:

  • As junções estão corretas: s.id_servidor = c.id_servidor e c.id_contrato = p.id_contrato.

  • Filtra pagamentos apenas de 2025 (BETWEEN '2025-01-01' AND '2025-12-31').

  • Garante contratos vigentes em 31/12/2025: c.data_inicio <= '2025-12-31' (iniciados até essa data) e c.data_fim IS NULL OR c.data_fim >= '2025-12-31' (não encerrados ou com fim após a data).

  • Agrupa por servidor e filtra com HAVING SUM(p.valor_pago) > 100000.

  • Usa INNER JOIN, o que exclui servidores sem pagamentos em 2025 (atende ao requisito de não incluir servidores sem pagamentos).

Alternativa E — ❌ Incorreta

SELECT s.nome, SUM(p.valor_pago)
FROM servidor s
LEFT JOIN contrato c ON s.id_servidor = c.id_servidor
LEFT JOIN pagamento p ON c.id_contrato = p.id_contrato
WHERE p.data_pagamento LIKE '2025%'
AND c.data_fim >= '2025-12-31'
GROUP BY s.nome
HAVING SUM(p.valor_pago) >= 100000;

Erros:

  1. LEFT JOIN incluiria servidores sem contratos ou pagamentos, mas o WHERE com p.data_pagamento LIKE '2025%' transforma o LEFT JOIN em INNER JOIN (porque filtra colunas da tabela à direita), então isso não é um problema grave. No entanto, o uso de LIKE para data é frágil e não recomendado.

  2. Não considera contratos com data_fim nula (apenas >= '2025-12-31').

  3. O HAVING usa >= 100000 em vez de > 100000 (enunciado pede "ultrapassou", ou seja, maior que, não maior ou igual). Embora seja uma diferença sutil, a banca pode considerar erro.

  4. Falta a condição c.data_inicio <= '2025-12-31' (embora contratos com data_fim >= '2025-12-31' provavelmente já tenham início anterior, não é garantido).

Conclusão: A alternativa D é a única que atende corretamente a todos os requisitos do enunciado.

Gabarito: letra D

Link permanente: /questoes/qg764195