计算每月的运行总量

时间:2016-07-13 15:25:38

标签: postgresql running-total

我们说我有这张桌子:

id; date; units
1; Jan 1; 1
2; Jan 2; 4
3; Feb 9; 6
4; Mar 1; 1
5; Mar 4; 2

我现在如何计算" accumulation_month"相应的栏目?计算应该在每个新月开始。

id; date; units; accumulated_month
1; Jan 1; 1; 1
2; Jan 2; 4; 5
3; Feb 9; 6; 6
4; Mar 1; 1; 1
5; Mar 4; 2; 3

我所能得到的就是:

id; date; units; accumulated_month
1; Jan 1; 1; 5
2; Jan 2; 4; 5
3; Feb 9; 6; 6
4; Mar 1; 1; 3
5; Mar 4; 2; 3

2 个答案:

答案 0 :(得分:2)

create table t (id int, date date, units int);
insert into t (id, date, units) values
(1, '2016-01-01', 1),
(2, '2016-01-02', 4),
(3, '2016-02-09', 6),
(4, '2016-03-01', 1),
(5, '2016-03-04', 2);

不清楚您是否需要月内总计或月内的总计。总月份:

select
    id, date, units,
    sum(units) over (partition by date_trunc('month', date)) as acumm
from t
order by 1,2
;
 id |    date    | units | acumm 
----+------------+-------+-------
  1 | 2016-01-01 |     1 |     5
  2 | 2016-01-02 |     4 |     5
  3 | 2016-02-09 |     6 |     6
  4 | 2016-03-01 |     1 |     3
  5 | 2016-03-04 |     2 |     3

如果您想在一个月内获得一个总计,那么请在窗口函数中添加一个订单:

select
    id, date, units,
    sum(units) over (
        partition by date_trunc('month', date)
        order by id
    ) as acumm
from t
order by 1,2
;
 id |    date    | units | acumm 
----+------------+-------+-------
  1 | 2016-01-01 |     1 |     1
  2 | 2016-01-02 |     4 |     5
  3 | 2016-02-09 |     6 |     6
  4 | 2016-03-01 |     1 |     1
  5 | 2016-03-04 |     2 |     3

答案 1 :(得分:1)

运行:

SELECT
    t1.id, 
    t1.date, 
    t1.units,
    SUM(t2.units) accumulated_month
FROM t t1 
    JOIN t t2 
        ON date_trunc('month', t1.date) = date_trunc('month', t2.date)
            AND t2.date <= t1.date
GROUP BY t1.id, t1.date, t1.units
ORDER BY t1.id

编辑:

简化的SQL:

SELECT
    t1.*, SUM(t2.units) accumulated_month
FROM t t1 
    JOIN t t2 
        ON date_trunc('month', t1.date) = date_trunc('month', t2.date)
            AND t2.date <= t1.date
GROUP BY t1.id
ORDER BY t1.id

逻辑

背后的逻辑是JOIN表格本身。然后对于t1 JOIN中的每一行,t2中满足两者(AND)的所有行:

  1. 同年/月
  2. t2.date&lt; = t1.date
  3. 使用ON个约束,到目前为止,t1中的每一行都会JOIN累计。因此,如果没有分组,你会得到类似的东西:

    ╔════╦════════════╦═══════╦════════════╦══════════╗
    ║ id ║    date    ║ units ║  t2_date   ║ t2_units ║
    ╠════╬════════════╬═══════╬════════════╬══════════╣
    ║  1 ║ 2016-01-01 ║     1 ║ 2016-01-01 ║        1 ║
    ║  2 ║ 2016-01-02 ║     4 ║ 2016-01-01 ║        1 ║
    ║  2 ║ 2016-01-02 ║     4 ║ 2016-01-02 ║        4 ║
    ║  3 ║ 2016-02-09 ║     6 ║ 2016-02-09 ║        6 ║
    ║  4 ║ 2016-03-01 ║     1 ║ 2016-03-01 ║        1 ║
    ║  5 ║ 2016-03-04 ║     2 ║ 2016-03-01 ║        1 ║
    ║  5 ║ 2016-03-04 ║     2 ║ 2016-03-04 ║        2 ║
    ╚════╩════════════╩═══════╩════════════╩══════════╝
    

    GROUP BY t1.id之后,您可以SUM(t2.units)获得您的期望。

相关问题