在MySQL中按ID计算基于月度收益率的年初至今复合收益率
按ID计算YTD复合收益率(MySQL 8.0)
要实现按ID分组计算年初至今的复合收益率,MySQL没有直接的乘积聚合函数,我们可以通过对数转换把乘法运算转为加法运算来实现,对应公式(1+r1)*(1+r2)*...*(1+rn)-1的SQL实现如下:
假设你的数据表名为returns,字段对应为id、name、date、monthly_return(如果实际字段名是中文,替换成对应名称即可),执行以下SQL:
SELECT id, name, -- 计算复合收益率:指数化对数求和结果,再减1 ROUND(EXP(SUM(LN(1 + monthly_return))) - 1, 4) AS ytd_compound_return FROM returns -- 可选:筛选当前年份的数据(如果需要严格YTD) WHERE YEAR(date) = YEAR(CURDATE()) GROUP BY id, name;
逻辑解释
LN(1 + monthly_return):将每个(1+月度收益率)转换为自然对数,把乘法运算转化为加法运算(数学原理:ln(a*b)=ln(a)+ln(b))SUM(...):按ID分组,对所有对数结果求和EXP(...):对求和结果取自然指数,还原为所有(1+月度收益率)的乘积ROUND(...,4):将结果保留4位小数,方便查看百分比形式(比如0.1016即10.16%)- 最后减1,得到最终的复合收益率
示例数据验证
针对你提供的示例数据,计算结果如下:
- ID1:
(1-0.02)*(1+0.05)*(1+0.06)*(1+0.01)-1 ≈ 0.1016(10.16%) - ID2:
(1-0.01)*(1+0.01)*(1+0.05)-1 ≈ 0.0499(4.99%) - ID3:
(1+0.05)*(1+0.05)-1 = 0.1025(10.25%)
注意事项
- 确保
1 + monthly_return > 0,否则LN()函数会报错,可添加过滤条件WHERE monthly_return > -1排除无效数据 - 如果需要按年份分组计算每年的YTD,可在
GROUP BY中加入YEAR(date),同时调整WHERE条件筛选对应年份
内容的提问来源于stack exchange,提问作者Lasse
相关产品推荐
相关产品推荐

