I got a select that groups the total value of a column, but also I need the percentage referring to each sum referring to the total sum!
As an example of today's return:
id|sum
1| 10
2| 50
3| 80
4| 20
5| 60
What I'm looking for: (the total is 220)
id|sum| %
1| 10|10/220
2| 50|50/220
3| 80|80/220
4| 20|20/220
5| 60|60/220
I am not sure if there's an easy way to got that result, using a sub select I could do this but I tought it not good and should have a better way.
The select is so simple:
Select
id,
sum(value)
From
table
Group By
id
But, that's the real select:
Select
OrcaItem.Cd_Produto,
OrcaItem.Ds_Produto,
OrcaItem.Cd_Produto || ' - ' || OrcaItem.Ds_Produto CdDs_Produto,
Estoque.Qt_Disponivel,
Sum(OrcaItem.Qt_Vendida) Qt_Vendida,
Sum(OrcaItem.Vr_TotalLiquido) Vr_Liquido, -- HERE!
Cast(Sum(
Case :piTipoCusto
When 0 Then (Produto.Vr_CustoAtual * OrcaItem.Qt_Vendida)
When 1 Then (OrcaItem.Vr_CustoAtual * OrcaItem.Qt_Vendida)
When 2 Then (OrcaItem.Vr_CustoFin * OrcaItem.Qt_Vendida)
When 3 Then (Produto.Vr_UltPcoCompra * OrcaItem.Qt_Vendida)
End
) As Numeric(15,2)) Vr_Custo,
Cast(Sum(
Case :piTipoCusto
When 0 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_CustoAtual * OrcaItem.Qt_Vendida)
When 1 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoAtual * OrcaItem.Qt_Vendida)
When 2 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoFin * OrcaItem.Qt_Vendida)
When 3 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_UltPcoCompra * OrcaItem.Qt_Vendida)
End
) As Numeric(15,2)) Vr_Lucro,
Sum(
Case :piTipoCusto
When 0 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_CustoAtual * OrcaItem.Qt_Vendida)
When 1 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoAtual * OrcaItem.Qt_Vendida)
When 2 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoFin * OrcaItem.Qt_Vendida)
When 3 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_UltPcoCompra * OrcaItem.Qt_Vendida)
End
) / Sum(OrcaItem.Vr_TotalLiquido) * 100 Pc_Lucro,
Produto.Cd_Linha,
Linha.Ds_Linha,
Produto.Cd_Grupo,
Grupo.Ds_Grupo
From
OrcaItem
Inner Join Orca On Orca.Nr_Orcamento = OrcaItem.Nr_Orcamento
Inner Join Estoque On Estoque.Cd_Produto = OrcaItem.Cd_Produto
Inner Join Produto On Produto.Cd_Produto = OrcaItem.Cd_Produto
Inner Join Linha On Linha.Cd_Linha = Produto.Cd_Linha
Inner Join Grupo On Grupo.Cd_Linha = Produto.Cd_Linha And
Grupo.Cd_Grupo = Produto.Cd_Grupo
Where
Orca.Fg_Situacao In ('F', 'R') And
Orca.Dt_Atendido Between :piDt_Inicio And :piDt_Final
Group By
OrcaItem.Cd_Produto,
OrcaItem.Ds_Produto,
CdDs_Produto,
Estoque.Qt_Disponivel,
Produto.Cd_Linha,
Linha.Ds_Linha,
Produto.Cd_Grupo,
Grupo.Ds_Grupo
Order By
Produto.Cd_Linha,
Produto.Cd_Grupo,
OrcaItem.Ds_Produto
Sum(OrcaItem.Vr_TotalLiquido) Vr_Liquido = total of each
The 'global' total is the sum of Vr_Liquido.
CodePudding user response:
What you are looking for is Window Functions.
CodePudding user response:
Assuming the simple select you show, you can use a window function, assuming you're using Firebird 3.0 or higher:
select id, sum_value, cast(sum_value as numeric(18,2)) / sum(sum_value) over()
from (
select id, sum("VALUE") as sum_value
from testdata
group by id
)
The over()
will aggregate over all rows. The cast to NUMERIC(18,2)
is needed to ensure the value is non-zero. Use a higher scale if you need more digits (or cast to double precision
).
For the more complex select, you take the same approach. Make the original query a derived table (or common table expression), and use the window function in the enclosing select list.