我在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'
。
是否可以开始对不是第一行的行进行求和?
答案 0 :(得分:2)
当然可以:
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;
我们的想法是用标志标记第一行和每个后续行,然后只汇总那些被标记的行。