基于Rank计算不同Tenor分组的历史值累计求和问题排查
修正按Tenor分组的最近N值求和SQL
看起来你的核心需求是针对不同Tenor,计算该分组下最近N个hist_rate的总和,并将这个总和显示在该分组的每一行,原SQL的问题出在使用了GROUP BY导致无法实现“全行显示总和”的效果,分组逻辑也没完全匹配需求。
问题分析
原SQL的GROUP BY子句把created_date, contributor, Tenor, hist_date, hist_rate作为分组键,这意味着每一行都会单独成组,SUM()只能计算当前行是否符合条件的hist_rate(要么是当前行的数值,要么是0),完全达不到“汇总最近N个值”的目的。另外,原子查询的PARTITION BY Tenor可能不够严谨——如果不同的created_date或contributor对应的Tenor数据是独立的,应该把这两个字段也加入分区,避免跨组汇总。
修正后的SQL
我们需要改用**窗口函数SUM() OVER()**来实现“在分组内汇总符合条件的值,并每行显示总和”的效果:
SELECT created_date, contributor, Tenor, hist_date, hist_rate, -- 根据Tenor类型,计算分组内最近N个hist_rate的总和 SUM(CASE WHEN Tenor = '1W' AND rank_no <= 3 THEN hist_rate WHEN Tenor = '3M' AND rank_no <= 5 THEN hist_rate WHEN Tenor = '6M' AND rank_no <= 10 THEN hist_rate -- 兼容原SQL中其他Tenor的逻辑,可根据实际需求调整 WHEN Tenor = 'O/N' AND rank_no <= 3 THEN hist_rate WHEN Tenor IN ('1M', '1Y') AND rank_no <= 10 THEN hist_rate ELSE 0 END) OVER (PARTITION BY created_date, contributor, Tenor) AS Calculation FROM ( SELECT created_date, contributor, Tenor, hist_date, hist_rate, Seq_no, -- 按[日期+贡献者+Tenor]分区,确保独立组的数据不交叉 RANK() OVER (PARTITION BY created_date, contributor, Tenor ORDER BY Seq_no DESC) AS rank_no FROM TableName ) A;
关键调整点
- 替换GROUP BY为窗口函数:
SUM() OVER(PARTITION BY ...)会在指定的分组内计算总和,并且每个行都会显示这个分组的汇总结果,完美匹配“所有行显示总和”的需求。 - 完善分区逻辑:将
created_date和contributor加入PARTITION BY,确保不同日期、不同贡献者的Tenor数据是独立计算的(如果你的业务中不需要这两个维度,可以去掉)。 - 精准匹配Tenor的求和规则:严格按照需求对
1W/3M/6M分别设置最近3/5/10个值的条件,同时保留原SQL中其他Tenor的逻辑,可根据实际业务调整。
效果说明
比如对于Tenor为1W的分组,rank_no <=3会筛选出该分组内最近的3条数据,SUM()会把这3条的hist_rate加总,然后这个总和会显示在该分组的每一行里。
内容的提问来源于stack exchange,提问作者viresh
相关产品推荐
相关产品推荐

