清除累积总和以及分组总和

时间:2018-09-23 14:39:31

标签: psql

我正在PostgreSQL 9.6.6

工作

为了可重复性,我将使用create tempory table创建一个“常量”表来进行播放:

create temporary table test_table as 
    select * from 
            (values 
                ('2018-01-01', 2),
                ('2018-01-01', 3),
                ('2018-02-01',  1),
                ('2018-02-01', 2))
            as t (month, count)

select * from test_table返回以下内容:

   month    | count 
------------+-------
 2018-01-01 |     2
 2018-01-01 |     3
 2018-02-01 |     1
 2018-02-01 |     2

所需的输出如下:

   month    | sum | cumulative_sum 
------------+-----+----------------
 2018-01-01 |   5 |              5
 2018-02-01 |   3 |              8

换句话说,这些值已被求和,按月分组,然后累积总和显示在另一列中。

问题在于,我知道实现这一目标的唯一方法有些令人费解。必须首先计算分组的总和(如使用sub select或with语句),然后使用针对该表的select语句计算运行中的计数,如下所示:

with sums as 
    (select month,
        sum(count) as sum
    from test_table
    group by 1)
select month,
    sum,
    sum(sum) over (order by month) as cumulative_sum
from sums

希望可以起作用的东西更像是...

select month,
    sum(count) as sum,
    sum(count) over (order by month) as cumulative_sum
from test_table
group by 1

但这返回

ERROR:  column "test_table.count" must appear in the GROUP BY clause or be used in an aggregate function
LINE 3:    sum(count) over (order by month) as cumulative_sum

group by子句的大惊小怪似乎无法满足PSQL。

TL,DR :PSQL中是否有一种方法可以仅使用单个select语句来计算组上的总和和组上的累计总和?更笼统地说,除了我在这个问题中使用的方法之外,还有没有一种“首选的”方式来完成此任务?

1 个答案:

答案 0 :(得分:1)

使用SUM作为分析函数的直觉是正确的,但是您需要对总和进行分析求和:

SELECT month,
    SUM(count) as sum,
    SUM(SUM(count)) OVER (ORDER BY month) AS cumulative_sum
FROM test_table
GROUP BY 1;

enter image description here

Demo

关于它为什么起作用,在发生GROUP BY子句之后应用分析函数。因此,当我们进行滚动总和时,实际上总和是可用的。