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

Clean cumulative sum alongside grouped sum

我在PostgreSQL 9.6.6

工作

为了可重复性,我将使用 create tempory table 创建一个 "constant" 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_tablereturns如下:

   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 语句计算 运行 计数 table,因此:

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

但是这个returns

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 语句来计算组的总和和组的累积和?更一般地说,除了我在这个问题中使用的方法之外,还有 "preferred" 方法来完成这个吗?

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

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

Demo

至于为什么会这样,分析函数是在 GROUP BY 子句发生后应用的。所以当我们去滚动总和时,总和实际上是可用的。