如何从动态行启动SUM()?

时间:2015-10-21 08:46:25

标签: sql postgresql

我在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=1opid='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=1opid='all'

问题是,下次可能是logid=600或其他。我不知道哪个行是subid=1opid='all'

是否可以开始对不是第一行的行进行求和?

1 个答案:

答案 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;

我们的想法是用标志标记第一行和每个后续行,然后只汇总那些被标记的行。