As tabelas a seguir devem ser utilizadas para responder à questão abaixo:
Em um banco de dados PostgreSQL da SCGE, instalado e funcionando em condições ideais, há cinco tabelas assim definidas:
– tabela dim_orgao (campos: id_orgao, cod_orgao, nome_orgao), que armazena informações das unidades administrativas do órgão público;
– tabela dim_tempo (campos: id_tempo, data_inicio, data_fim, mes, ano), responsável por representar o calendário analítico usado nas consultas e agregações;
– tabela dim_elemento (campos: id_elemento, cod_elemento, descricao), que contém a classificação contábil e natureza dos gastos;
– tabela staging_despesas (campos: cod_orgao, cod_elemento, data_empenho, valor), utilizada como área temporária de carregamento de dados brutos provenientes dos sistemas transacionais;
– tabela fato_despesas (campos: id_orgao, id_tempo, id_elemento, valor_total), que consolida as medidas financeiras agregadas.
Estas tabelas já foram populadas com dados e estão sendo usadas no desenvolvimento de um Data Warehouse, visando consolidar informações de execução orçamentária e custos operacionais.
Um Gestor Governamental está validando os dados financeiros antes de publicá-los em um dashboard de uma ferramenta conectada ao Data Warehouse desenvolvido no PostgreSQL da SCGE. Os dados vêm das tabelas dim_orgao, dim_tempo, dim_elemento e fato_despesas. Para isso, ele utiliza a consulta SQL abaixo para gerar a base consolidada que será disponibilizada.
SELECT
o.nome_orgao AS orgao,
e.descricao AS elemento,
t.ano,
I AS total_despesas
FROM fato_despesas f
JOIN dim_orgao o ON f.id_orgao = o.id_orgao
JOIN dim_tempo t ON f.id_tempo = t.id_tempo
JOIN dim_elemento e ON f.id_elemento = e.id_elemento
GROUP BY o.nome_orgao, e.descricao, t.ano
ORDER BY t.ano, o.nome_orgao;
Para gerar valores consolidados de forma correta, a lacuna I deve ser corretamente preenchida com:
AROUND(SUM(f.valor_total), 2)
BSUM(f.valor_total) + RANK() OVER (ORDER BY t.ano)
CSUM(f.valor_total) + MAX(f.valor_total)
DCOUNT(f.valor_total)
ESUM(f.valor_total) OVER (PARTITION BY t.ano)
Revelar gabarito e comentário▾
GabaritoA — ROUND(SUM(f.valor_total), 2)
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 no PostgreSQL: agregação com GROUP BY e funções de janela
Gabarito: letra A. Para consolidar os valores financeiros por órgão, elemento e ano, a lacuna deve ser preenchida com ROUND(SUM(f.valor_total), 2), pois a consulta usa GROUP BY e a função de agregação SUM soma os valores de cada grupo, enquanto ROUND arredonda o resultado para duas casas decimais — adequado para valores monetários. As demais alternativas misturam funções de janela ou contagens que não produzem o total consolidado esperado.
A consulta apresentada é um exemplo clássico de consulta analítica em um Data Warehouse com esquema estrela: a tabela fato_despesas é a tabela de fatos, contendo as medidas (valor_total) e as chaves estrangeiras para as dimensões (id_orgao, id_tempo, id_elemento). As tabelas dim_orgao, dim_tempo e dim_elemento são as dimensões, que fornecem o contexto descritivo (nome do órgão, descrição do elemento, ano). O JOIN entre a fato e cada dimensão é feito pelas chaves correspondentes, e o GROUP BY agrupa os registros por o.nome_orgao, e.descricao e t.ano. Para cada grupo, precisamos de uma medida agregada: a soma dos valores de f.valor_total.
A função SUM é uma função de agregação que retorna a soma de uma expressão para todas as linhas do grupo. O ROUND é uma função matemática que arredonda um número para um número especificado de casas decimais. No PostgreSQL, ROUND(numeric, integer) arredonda o valor para o número de casas decimais indicado. Como valor_total é um campo monetário, é boa prática arredondar para 2 casas decimais para evitar erros de exibição e garantir consistência nos relatórios financeiros.
A alternativa B (SUM(f.valor_total) + RANK() OVER (ORDER BY t.ano)) mistura uma função de agregação com uma função de janela. RANK() é uma função de janela que atribui uma classificação a cada linha dentro de uma partição, mas aqui ela é usada sem PARTITION BY, o que a torna uma classificação global. Somar essa classificação ao total distorce o valor consolidado, adicionando um número arbitrário (a posição no ranking) ao total de despesas. Além disso, a função de janela é avaliada após o GROUP BY, mas o resultado não é uma agregação simples — é uma combinação inválida para o propósito de consolidar valores.
A alternativa C (SUM(f.valor_total) + MAX(f.valor_total)) também soma o total com o valor máximo do grupo. Isso não faz sentido para consolidar despesas: o total já inclui o valor máximo, então somá-lo novamente duplicaria parte do valor, inflando o resultado. Não há justificativa lógica para adicionar o máximo ao total em um relatório de despesas.
A alternativa D (COUNT(f.valor_total)) conta o número de registros no grupo, não a soma dos valores. Isso retornaria a quantidade de lançamentos de despesas, não o valor total. O enunciado pede "valores consolidados" e o alias é total_despesas, indicando que se espera um valor monetário, não uma contagem.
A alternativa E (SUM(f.valor_total) OVER (PARTITION BY t.ano)) usa uma função de janela com PARTITION BY t.ano. Essa função calcula a soma de todos os registros do mesmo ano, independentemente do órgão ou elemento, e repete esse valor para cada linha do grupo. Isso não respeita o agrupamento por o.nome_orgao, e.descricao, t.ano — o resultado seria o total anual repetido para cada combinação, não o total por grupo. Além disso, a função de janela é avaliada após o GROUP BY, mas o PARTITION BY redefine o escopo, ignorando o agrupamento.
A pegadinha desta questão está em distinguir funções de agregação (que operam sobre grupos definidos pelo GROUP BY) de funções de janela (que operam sobre partições definidas pelo OVER). A banca explora a confusão entre SUM com GROUP BY e SUM com OVER, além de misturar funções que não produzem o total consolidado.
1GROUP BY define grupos
2SUM agrega por grupo
3ROUND arredonda 2 casas
4OVER redefine escopo
LEVEL · soulevel.com.br
Alternativa A — ✅ Correta ⟵ GABARITO
ROUND(SUM(f.valor_total), 2) é a expressão correta. SUM agrega os valores de f.valor_total para cada grupo definido pelo GROUP BY (órgão, elemento, ano), e ROUND arredonda o resultado para duas casas decimais, adequado para valores monetários. Isso gera o total de despesas por grupo, exatamente o que o alias total_despesas sugere.
Alternativa B — ❌ Incorreta
SUM(f.valor_total) + RANK() OVER (ORDER BY t.ano) mistura agregação com função de janela. RANK() atribui uma classificação baseada na ordem do ano, mas somar essa classificação ao total não tem sentido lógico — o resultado seria o total acrescido de um número arbitrário (a posição no ranking). Além disso, a função de janela é avaliada após o GROUP BY, mas o RANK sem PARTITION BY considera todas as linhas, não os grupos.
Alternativa C — ❌ Incorreta
SUM(f.valor_total) + MAX(f.valor_total) soma o total com o valor máximo do grupo. Isso duplica parte do valor (o máximo já está incluído no total), inflando o resultado. Não há justificativa para adicionar o máximo ao total em um relatório de despesas consolidadas.
Alternativa D — ❌ Incorreta
COUNT(f.valor_total) conta o número de registros no grupo, não a soma dos valores. O resultado seria a quantidade de lançamentos, não o valor total das despesas. O alias total_despesas e o contexto de consolidação financeira indicam que se espera um valor monetário, não uma contagem.
Alternativa E — ❌ Incorreta
SUM(f.valor_total) OVER (PARTITION BY t.ano) usa uma função de janela que calcula a soma de todos os registros do mesmo ano, ignorando o agrupamento por órgão e elemento. O resultado seria o total anual repetido para cada combinação, não o total por grupo. A função de janela redefine o escopo da soma, contrariando o GROUP BY.
NÃO CAIA NESSA!
A banca explora a confusão entre funções de agregação (com GROUP BY) e funções de janela (com OVER). A alternativa E parece plausível, mas o PARTITION BY t.ano ignora o agrupamento por órgão e elemento, retornando o total anual repetido. Lembre-se: com GROUP BY, use funções de agregação simples como SUM, COUNT, MAX; funções de janela são para cálculos que não colapsam linhas.
PEGA ESSA DICA!
Para identificar a função correta, pergunte-se: "O resultado deve ter uma linha por grupo (agregação) ou uma linha por registro com um valor calculado (janela)?" Se for agregação, use SUM com GROUP BY. Se for janela, use OVER. E para valores monetários, sempre aplique ROUND para 2 casas decimais.