表的累积总和

时间:2014-07-20 15:22:23

标签: sql postgresql window-functions cumulative-sum

在Postgres中对表执行累积和的最佳方法是什么,以便在将更多字段/列添加到表中时可以带来最佳性能和灵活性。

表格

    a   b   d
1   59  15  181
2       16  268
3           219
4           102

累积

    a   b   d
1   59  15  181
2       31  449
3           668
4           770

3 个答案:

答案 0 :(得分:3)

用于运行总和的窗口函数。

SELECT sum(a) OVER (ORDER BY d) as "a",
       sum(b) OVER (ORDER BY d) as "b",
       sum(d) OVER (ORDER BY d) as "d" 
FROM table;

如果您有多个运行总和,请确保订单相同。


重要的是要注意,如果您希望您的列在问题中显示为聚合表(每个字段都是唯一排序的),那么它就会更加复杂。


更新:我已修改查询以执行所需的排序,但没有给定的公共字段。

SQL小提琴:(1) Only Aggregates(2) Source Data Beside Running Sum

WITH 
rcd AS ( 
  select row_number() OVER() as num,a,b,d 
  from tbl
),
sorted_a AS (
  select row_number() OVER(w1) as num, sum(a) over(w2) a
  from tbl
  window w1 as (order by a nulls last),
         w2 as (order by a nulls first)
),
sorted_b AS (
  select row_number() OVER(w1) as num, sum(b) over(w2) b
  from tbl
  window w1 as (order by b nulls last),
         w2 as (order by b nulls first)
),
sorted_d AS (
  select row_number() OVER(w1) as num, sum(d) over(w2) d
  from tbl
  window w1 as (order by d nulls last),
         w2 as (order by d nulls first)
)

SELECT sorted_a.a, sorted_b.b, sorted_d.d 
FROM rcd 
JOIN sorted_a USING(num)
JOIN sorted_b USING(num)
JOIN sorted_d USING(num)
ORDER BY num;

答案 1 :(得分:3)

你可以使用窗口函数,但是你需要额外的逻辑来避免NULL s的值:

SELECT id,
       (case when a is not null then sum(a) OVER (ORDER BY id) end) as a,
       (case when b is not null then sum(b) OVER (ORDER BY id) end) as b,
       (case when d is not null then sum(d) OVER (ORDER BY id) end) as d 
FROM table;

这假定指定排序的第一列称为id

答案 2 :(得分:3)

我认为你真正想要的是:

SELECT id
     , sum(a) OVER (PARTITION BY a_grp ORDER BY id) as a
     , sum(b) OVER (PARTITION BY b_grp ORDER BY id) as b
     , sum(d) OVER (PARTITION BY d_grp ORDER BY id) as d 
FROM  (
   SELECT *
        , count(a IS NULL OR NULL) OVER (ORDER BY id) as a_grp
        , count(b IS NULL OR NULL) OVER (ORDER BY id) as b_grp
        , count(d IS NULL OR NULL) OVER (ORDER BY id) as d_grp
   FROM   tbl
   ) sub
ORDER  BY id;

表达式count(col IS NULL OR NULL) OVER (ORDER BY id)在子查询a中为bdsub形成连续的非空行组。

在外部查询中,我们运行累积总和每组NULL值构成他们自己的群组并自动保留NULL。无需额外的CASE声明。

SQL Fiddle(列a添加了一些值以证明效果)。