计算PostgreSQL中的累积和

You*_*tan 62 sql postgresql analytic-functions cumulative-sum window-functions

我想找到累积或运行的字段数量,并将其从分段插入表格.我的暂存结构是这样的:

ea_month    id       amount    ea_year    circle_id
April       92570    1000      2014        1
April       92571    3000      2014        2
April       92572    2000      2014        3
March       92573    3000      2014        1
March       92574    2500      2014        2
March       92575    3750      2014        3
February    92576    2000      2014        1
February    92577    2500      2014        2
February    92578    1450      2014        3          
Run Code Online (Sandbox Code Playgroud)

我希望我的目标表看起来像这样:

ea_month    id       amount    ea_year    circle_id    cum_amt
February    92576    1000      2014        1           1000 
March       92573    3000      2014        1           4000
April       92570    2000      2014        1           6000
February    92577    3000      2014        2           3000
March       92574    2500      2014        2           5500
April       92571    3750      2014        2           9250
February    92578    2000      2014        3           2000
March       92575    2500      2014        3           4500
April       92572    1450      2014        3           5950
Run Code Online (Sandbox Code Playgroud)

我对如何实现这个结果非常困惑.我想用PostgreSQL实现这个结果.

任何人都可以建议如何实现这个结果集?

Erw*_*ter 103

基本上,你需要一个窗口功能.这是当今的标准功能.除了真正的窗口函数,您还可以通过附加一个子句将任何聚合函数用作Postgres中的窗口函数OVER.

这里的特殊困难是获得正确的分区和排序顺序:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id ORDER BY ea_year, ea_month) AS cum_amt
FROM   tbl
ORDER  BY circle_id, month;
Run Code Online (Sandbox Code Playgroud)

而且没有 GROUP BY.

每行的总和是从分区中的第一行到当前行计算的 - 或者引用手册来确切:

默认框架选项是RANGE UNBOUNDED PRECEDING,与RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.相同.使用 ORDER BY,这将帧设置为从分区启动到当前行的最后一个ORDER BY对等体的所有行.

...这是你追求的累计或运行金额.大胆强调我的.

具有相同行的(circle_id, ea_year, ea_month)是此查询中的"对等".所有这些都显示相同的运行总和,所有对等项都添加到总和中.但是我假设你的表是UNIQUE打开的(circle_id, ea_year, ea_month),那么排序顺序是确定性的,没有行有同行.

现在,ORDER BY ... ea_month 不会使用月份名称的字符串.Postgres将根据区域设置按字母顺序排序.

如果您date的表中存储了实际值,则可以正确排序.如果没有,我建议更换ea_year,并ea_month与一列mondate在表格中.

虽然坚持不幸的布局,这将工作:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id ORDER BY mon) AS cum_amt
FROM   (SELECT *, to_date(ea_year || ea_month, 'YYYYMonth') AS mon FROM tbl)
ORDER  BY circle_id, mon;
Run Code Online (Sandbox Code Playgroud)

  • @YousufSultan:大部分时间都有比光标更好的解决方案.这绝对是一个新问题的东西.请开始一个新问题. (4认同)
  • 这是一个具有更简单查询的类似问题的链接(创建运行总计并不总是需要“PARTITION”):/sf/answers/399052111/ (4认同)