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:
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.
Não há filtro para contratos vigentes em 31/12/2025 (falta c.data_fim >= '2025-12-31').
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).
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:
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.
Não há filtro de contratos vigentes.
Não há HAVING para filtrar soma > 100000.
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:
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.
Não considera contratos com data_fim nula (apenas >= '2025-12-31').
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.
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