我在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'
可以开始对不是第一行的行求和吗?

最佳答案

当然有可能:

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/

10-11 06:33