从PostgreSQL数据库获取每月和每年的总运行总数

时间:2018-01-08 11:40:48

标签: sql postgresql window-functions cumulative-sum

这是我的样本数据(表“sumtest”):

+-------+--------+-------+
| month |  value |  year |
+-------+--------+-------+
|     1 |     10 |  2017 |
|     2 |      0 |  2017 |
|     2 |     10 |  2016 |  # note: different year
|     2 |      5 |  2017 |
|     3 |     88 |  2017 |
|     3 |      2 |  2017 |
|     5 |      1 |  2017 |
|     5 |      4 |  2017 |
|     5 |      5 |  2017 |
+-------+--------+-------+

我想得到每个月的总价值,以及该特定月份每年的总运行总额,即我希望我的结果如下:

+------+-------+-----------+----------+
| year | month | sum_month | sum_year |
+------+-------+-----------+----------+
| 2016 |     2 |        10 |       10 |
| 2017 |     1 |        10 |       10 |
| 2017 |     2 |         5 |       15 |
| 2017 |     3 |        90 |      105 |
| 2017 |     5 |        10 |      115 |
+------+-------+-----------+----------+

我是Postgres的新手,我尝试了以下内容:

    SELECT *, sum(value) OVER (PARTITION BY month, year) AS sum_month, 
sum(value) OVER (PARTITION BY year) AS sum_year
    FROM sumtest
    ORDER BY year, month

但是这会为每个原始条目产生一行,并且每行列出的总年度总和而不是到此为止的累计总和:

+-------+-------+------+-----------+----------+
| month | value | year | sum_month | sum_year |
+-------+-------+------+-----------+----------+
|     2 |    10 | 2016 | '10'      | '10'     |
|     1 |    10 | 2017 | '10'      | '115'    |
|     2 |     5 | 2017 | '5'       | '115'    |
|     2 |     0 | 2017 | '5'       | '115'    |
|     3 |     2 | 2017 | '90'      | '115'    |
|     3 |    88 | 2017 | '90'      | '115'    |
|     5 |     4 | 2017 | '10'      | '115'    |
|     5 |     1 | 2017 | '10'      | '115'    |
|     5 |     5 | 2017 | '10'      | '115'    |
+-------+-------+------+-----------+----------+

我也尝试过使用GROUP BY,这对于几个月的累积总和有效,但之后我现在没有考虑如何包含年度的累计总数(因为不应该按月分组)。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您可以在查询上方添加MAXGROUP BY,在ORDER BY内添加OVER()

select year,month,MAX( sum_month) sum_month,  MAX(sum_year) sum_year 
FROM
(
 SELECT *, sum(value) OVER (PARTITION BY month, year ORDER BY year,month) AS sum_month, 
sum(value) OVER (PARTITION BY year ORDER BY year,month) AS sum_year
    FROM sumtest
)  a
GROUP BY year,month;

DEMO

答案 1 :(得分:1)

制备

t=# create table s(a text,m int, v int, y int, b text);
CREATE TABLE
t=# copy s from stdin delimiter '|';
>> \.
COPY 9
t=# alter table s drop column a;
ALTER TABLE
t=# alter table s drop column b;
ALTER TABLE

查询:

t=# select distinct y,m,sum(v) over (partition by m,y), sum(v) over (partition by y order by m) from s order by y,m;
  y   | m | sum | sum
------+---+-----+-----
 2016 | 2 |  10 |  10
 2017 | 1 |  10 |  10
 2017 | 2 |   5 |  15
 2017 | 3 |  90 | 105
 2017 | 5 |  10 | 115
(5 rows)

已更新 - 我完全错过累积