Reputation: 93
I'am trying to do a running total (without success) over a calculated column on sql.
My original code:
select t.codigo, t.nome, t.total
from(
select codigo, nome, SUM(CASE When ANO = 2018 Then VLCOMPRA Else 0 End ) as total
from clientes
left join ACUMTERC on ACUMTERC.TPTERC = 2 and TPOPER = 2 AND ACUMTERC.TERCEIRO = CLIENTES.CODIGO
group by codigo, nome) as t
ORDER BY total DESC
What i tried:
select t.codigo, t.nome, t.total, SUM(t.total) OVER(PARTITION BY t.codigo ORDER BY t.codigo) RunningTotal
from( select codigo, nome, SUM(CASE When ANO = 2018 Then VLCOMPRA Else 0 End ) as total from clientes left join ACUMTERC on ACUMTERC.TPTERC = 2 and TPOPER = 2 AND ACUMTERC.TERCEIRO = CLIENTES.CODIGO group by codigo, nome) as t
ORDER BY total DESC
My result:
codigo | nome | total | Running total
-------+-------+-------+---------------
000001 | name1 | 300 ! 300
000003 | name3 | 200 | 200
000002 | name2 | 100 | 100
What i need:
codigo | nome | total | Running total
-------+-------+-------+---------------
000001 | name1 | 300 ! 300
000003 | name3 | 200 | 500
000002 | name2 | 100 | 600
Any help? Thank you.
Upvotes: 0
Views: 80
Reputation: 4061
You can do it this way, using ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT:
select t.codigo, t.nome, t.total,
SUM(t.total) OVER(ORDER BY t.codigo ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) RunningTotal
from( select codigo, nome, SUM(CASE When ANO = 2018 Then VLCOMPRA Else 0 End ) as total from clientes left join ACUMTERC on ACUMTERC.TPTERC = 2 and TPOPER = 2 AND ACUMTERC.TERCEIRO = CLIENTES.CODIGO group by codigo, nome) as t
ORDER BY total DESC
An example with data:
with tbl as
(
select '000001' as codigo , 'name1' as nome, 300 as total, 300 as Running_total
union select '000003' , 'name3' , 200 , 200
union select '000002' , 'name2' , 100 , 100
)
select t.codigo, t.nome, t.total,
SUM(t.total) OVER(ORDER BY t.codigo asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) RunningTotal
from tbl as t
ORDER BY codigo asc
with tbl as
(
select '000001' as codigo , 'name1' as nome, 300 as total, 300 as Running_total
union select '000003' , 'name3' , 200 , 200
union select '000002' , 'name2' , 100 , 100
)
select t.codigo, t.nome, t.total,
SUM(t.total) OVER(ORDER BY t.codigo asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) RunningTotal
from tbl as t
ORDER BY codigo asc
Output:
codigo nome total RunningTotal
000001 name1 300 300
000002 name2 100 400
000003 name3 200 600
Upvotes: 0
Reputation: 222412
I strongly suspect that your query can be simplified:
join
When it comes to your requirement, you can do a window sum()
.
I would also strongly suggest to prefix each column with the table it belongs to: this makes the query unambiguous about the data structures; I made a few assumptions that you might want to check (I also used table aliases to shorten the query).
Consider:
select
c.codigo,
c.nome,
coalesce(sum(a.vlcompra), 0) as total,
sum(coalesce(sum(a.vlcompra), 0))
over(order by coalesce(sum(a.vlcompra), 0) desc) running_total
from clientes c
left join acumterc a
on a.tpterc = 2
and a.tpoper = 2
and a.terceiro = c.codigo
and a.ano = 2018
group by c.codigo, c.nome
Upvotes: 1