我在PostgrSQL
中有一个查询,它生成以下数据:
logid subid opid date qty1 qty2
1 1 remove 1.1.15 100 0
2 2 remove 1.1.15 250 0
3 1 add 1.1.15 -450 0
4 3 arrive 1.1.15 320 0
5 1 all 1.1.15 320 500
6 4 remove 2.1.15 5 0
7 5 remove 2.1.15 6 0
8 2 all 3.1.15 50 500
基本上每个
opid
都是先分开排序的,subid
表示它在排序顺序中的位置。。。然后我将所有的操作合并在一起,并将它们转换成新的排序器logid
。输出如我前面所述。我需要添加一个
SUM()
列来处理案例。我想从
subid=1
和opid='all'
的行开始这是我写的:
sum(case when opid = 'all' and subid=1 then qty2+qty1
when opid = 'all' and subid>1 then qty1
when opid = 'remove' then -qty
when opid = 'add' then qty
else 0
end) over (order by logid) as A
这就提供了:
logid subid opid date qty1 qty2 A
1 1 remove 1.1.15 100 0 -100 / -100
2 2 remove 1.1.15 250 0 -350 / -100-250
3 1 add 1.1.15 -450 0 -800 / -350 + (-450)
4 3 arrive 1.1.15 320 0 -800 / -800 + 0
5 1 all 1.1.15 320 500 20 / -800 +320+500
6 4 remove 2.1.15 5 0 15 / 20-5
7 5 remove 2.1.15 6 0 9 / 15-6
8 2 all 3.1.15 50 500 59 / 9+50
我想要的是:
logid subid opid date qty1 qty2 A
1 1 remove 1.1.15 100 0 0
2 2 remove 1.1.15 250 0 0
3 1 add 1.1.15 -450 0 0
4 3 arrive 1.1.15 320 0 0
5 1 all 1.1.15 320 500 820 / 320+500
6 4 remove 2.1.15 5 0 815 / 820-5
7 5 remove 2.1.15 6 0 809 / 815-6
8 2 all 3.1.15 50 500 859 / 809+50
意味着总和应该从
logid=5
开始,因为这一行有subid=1
和opid='all'
问题是下次它可能是
logid=600
或其他什么东西。我不知道哪一行是subid=1
和opid='all'
。可以开始对不是第一行的行求和吗?
最佳答案
当然有可能:
with ops as (
select *,
sum(case when subid=1 and opid='all' then 1 else 0 end)
over (order by logid) as flag
from (YOUR_QUERY)
)
select *,
sum(case
when opid = 'all' and subid=1 then qty2+qty1
when opid = 'all' and subid>1 then qty1
when opid = 'remove' then -qty1
when opid = 'add' then qty1
else 0
end * sign(flag))
over (order by logid) as A
from ops
order by logid;
其思想是用一个标志标记第一行和随后的每一行,然后只汇总那些被标记的行。
关于sql - 如何从动态行启动SUM()?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33254758/