【问题标题】:How to calculate sum based on other rows如何根据其他行计算总和
【发布时间】:2015-12-29 13:58:32
【问题描述】:

我有一个帐户交易表,其中列出了帐户中的所有活动。

id  qty  
1     100    
2     200     
3     -50     
4     20     

id 列表示实时活动,因为2 发生在1 之后,而4 发生在3 之后。

我需要添加一列,每行给出当前总和:

id  qty    total_sum
1   100    100      / 0 + 100
2   200    300      / 100 + 200
3   -50    250      / 300 - 50
4    20     270      / 250 + 20

这很简单。但是我的表很大,它包含非常旧的行,它们的数据并不正确。为了避免这种情况,我想计算 从底部到顶部的总和,这样至少最新的记录将具有正确的值。就我而言,这是可行的,因为对于每个用户,我总是将当前更新的 total_sum 保存为今天......所以我有一个开始的价值。

在这种情况下(+ 将被视为 --+ )我得到的是:

id  qty    total_sum
1   100    0      / 100 - 100
2   200    100 / 300 - 200
3   -50    300      / 250 + 50
4   20     250      / init_value - 20

问题是在每一行中total_sum 在对行执行操作之前显示总和。例如,在第 2 行中,它显示 total_sum=100,这是在第 2 行的操作被处理之前。

如何修复它以显示第一个 total_sum 列但从按钮计算?

基本上我需要的是:

id  qty    total_sum
1   100    100
2   200    300
3   -50    250
4   20     init_value (which is 270)

这是我的代码:

SELECT id,qty,(select init_value from x where .....)
    - Sum(a.qty)OVER(ORDER BY id DESC) as total_sum
FROM    a
ORDER  BY id ASC

我该如何解决? (PostgreSQL 9.3)

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    您需要使用 LEAD/LAG 函数来访问下一个/上一个数量并在 SUM 中使用。

    SQL Fiddle

    PostgreSQL 9.3 架构设置

    create table myt(
      id_ integer,
      qty_ integer
      );
    
    insert into myt values(1,100);
    insert into myt values(2,200);
    insert into myt values(3,-50);
    insert into myt values(4,20);
    

    查询 1

    select id_, qty_,
    lead(qty_) over (order by id_) qty2
    from myt
    order by id_
    

    Results

    | id_ | qty_ |   qty2 |
    |-----|------|--------|
    |   1 |  100 |    200 |
    |   2 |  200 |    -50 |
    |   3 |  -50 |     20 |
    |   4 |   20 | (null) |
    

    查询 2

    select id_, qty_,
    270 - coalesce((sum(qty2) over (order by id_ desc)),0) total_sum
    from (
      select id_, qty_,
      lead(qty_) over (order by id_) qty2
      from myt
    ) c
    order by id_
    

    Results

    | id_ | qty_ | total_sum |
    |-----|------|-----------|
    |   1 |  100 |       100 |
    |   2 |  200 |       300 |
    |   3 |  -50 |       250 |
    |   4 |   20 |       270 |
    

    【讨论】:

      最近更新 更多