如何在PostgreSQL中基于每日涨跌幅计算累计价值(初始值100)
问题描述
我有一张名为performance的表,结构及数据如下:
| date | percent_change |
|---|---|
| 2022/12/01 | 2 |
| 2022/12/02 | -1 |
| 2022/12/03 | 3 |
假设初始价值为100,需要编写PostgreSQL查询语句,计算截至每日的累计价值,期望输出如下:
| date | percent_change | cumulative value |
|---|---|---|
| 2022/12/01 | 2 | 102 |
| 2022/12/02 | -1 | 100.98 |
| 2022/12/03 | 3 | 104.0094 |
解决方案
可以通过对数与指数转换实现累积乘积,结合窗口函数计算每日累计价值,对应的PostgreSQL查询语句如下:
SELECT date, percent_change, ROUND(100 * EXP(SUM(LN(1 + percent_change::numeric / 100)) OVER (ORDER BY date)), 4) AS cumulative_value FROM performance ORDER BY date;
逻辑说明
- 转换变化率为乘数:将百分比变化转换为价值乘数,公式为
1 + percent_change::numeric / 100,例如2%对应1.02,-1%对应0.99。 - 实现累积乘积:PostgreSQL没有原生的累积乘积窗口函数,通过
LN()取自然对数将乘法转为加法,用SUM() OVER (ORDER BY date)计算对数的累积和,最后用EXP()还原为乘积。 - 计算最终价值:将累积乘积乘以初始值100,用
ROUND()保留4位小数以匹配期望输出格式。
执行该查询后,输出结果与需求完全一致。
内容的提问来源于stack exchange,提问作者shyam yadav
相关产品推荐
相关产品推荐

