PostgreSQL,累积金额与间隔

时间:2017-08-23 17:51:49

标签: sql postgresql

你好,我有这个示例数据集:

 employee_id | amount     |    cumulative_amount
-------------+------------+-----------------
           2 |        100 | 100
           6 |        220 | 320
           7 |         45 | 365
           8 |         50 | 415
           9 |        110 | 525
          16 |        300 | 825
          17 |        250 | 1075
          18 |        200 | 1275

和间隔,让我们说300: 我想只选择符合条件的行,条件为:

如果它是> =先前值+间隔,则选择值 (例如,如果开始Val = 100,则下一个匹配行是累积量> = 400,依此类推) :

   employee_id | amount     |    cumulative_amount
  -------------+------------+-----------------
             2 |        100 | 100 <-- $Start
             6 |        220 | 320 - 400
             7 |         45 | 365 - 400
             8 |         50 | 415 <-- 1
             9 |        110 | 525 - 715 (prev value (415)+300)
            16 |        300 | 825 <-- 2
            17 |        250 | 1075 - 1125 (825+300)
            18 |        200 | 1275 <-- 3

所以最后的结果是:

           employee_id | amount     |    cumulative_amount
          -------------+------------+-----------------
                     2 |        100 | 100 
                     8 |         50 | 415 
                    16 |        300 | 825 
                    18 |        200 | 1275 

如何以最有效的方式在PostgreSQL中实现这一目标?

列cumulative_amount是列数量的渐进总和 它在另一个查询中计算,结果是上面的数据集,表由employee_id排序。

问候。

1 个答案:

答案 0 :(得分:0)

不是说这是最有效的方式,但可能是最简单的方法:

s=# create table s1(a int, b int, c int);
CREATE TABLE
Time: 10.262 ms
s=# copy s1 from stdin delimiter '|';
...
s=# with g as (select generate_series(100,1300,300) s)
, o as (select *,sum(b) over (order by a) from s1)
, c as (select *, min(sum) over (partition by g.s)
from o
join g on sum >= g.s and sum < g.s + 300
)
select a,b,sum from c
where sum = min
;
 a  |  b  | sum
----+-----+------
  2 | 100 |  100
  8 |  50 |  415
 16 | 300 |  825
 17 | 250 | 1075
(4 rows)

这里我使用了order by a,因为你的累积总和是第一列(与第三行核对)