我想找到累积或运行的字段数量,并将其从分段插入表格。我的暂存结构是这样的:
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
我希望我的目标表看起来像这样:
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
我对如何实现这一结果非常困惑。我想用PostgreSQL实现这个结果。
有人可以建议如何实现这个结果集吗?
答案 0 :(得分:91)
基本上,你需要window function。这是当今的标准功能。除了正版窗口函数之外,您还可以通过附加OVER
子句将任何聚合函数用作Postgres中的窗口函数。
这里的特殊困难是让分区和排序顺序正确:
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;
此处否 GROUP BY
。
每行的总和是从分区的第一行到当前行计算的 - 或准确引用the manual:
默认框架选项为
RANGE UNBOUNDED PRECEDING
,即 与RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
相同。同ORDER BY
,这会将框架设置为分区中的所有行 从当前行的ORDER BY
对等开始。
...这是您追求的累积或运行金额。大胆强调我的。
此查询中具有相同(circle_id, ea_year, ea_month)
的行是" peer" 。所有这些都显示相同的运行总和,所有对等项都添加到总和中。但我假设你的表在UNIQUE
上是(circle_id, ea_year, ea_month)
,那么排序顺序是确定性的,没有行有对等。
现在,ORDER BY ... ea_month
无法使用月份名称的字符串 。 Postgres将根据区域设置按字母顺序排序。
如果您的表中存储了实际的date
值,则可以正确排序。如果没有,我建议将[{1}}和ea_year
替换为表格中date
类型的ea_month
列。
虽然坚持不幸的布局,但这将有效:
to_char(mon, 'Month') AS ea_month
to_char(mon, 'YYYY') AS ea_year