SQL Server 2017 按客户端分区按时间排序实现累计求和咨询
SQL Server 2017 分区累计求和实现
针对提出的两项计算规则,可直接使用SQL Server 2017原生支持的窗口函数完成计算,无需额外编写复杂自连接逻辑。
计算规则对齐
- 分区范围:按
client字段拆分独立计算分组,不同客户的累计金额互不交叉 - 累计逻辑:每个分组内按
date_tm升序排序,逐行累加当前行的sum_pay支付金额
可直接运行的完整测试代码
-- 复现测试数据集 create table #clients ( client nvarchar(1), date_tm datetime, sum_pay int, desirable_result int ) insert into #clients (client, date_tm, sum_pay, desirable_result) select '1', '2020-01-01', 10, 10 union all select '1', '2020-01-02', 20, 30 union all select '2', '2020-01-03', 20, 60 union all select '2', '2020-01-01', 20, 20 union all select '2', '2020-01-02', 20, 40 union all select '3', '2020-01-01', 20, 20 union all select '3', '2020-01-04', 20, 70 union all select '3', '2020-01-02', 30, 50 -- 累计求和核心查询 SELECT client, date_tm, sum_pay, SUM(sum_pay) OVER ( PARTITION BY client -- 按client分区 ORDER BY date_tm -- 分区内按交易时间排序 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -- 从分区第一行累加到当前行 ) AS calculated_cumulative, desirable_result FROM #clients ORDER BY client, date_tm -- 清理测试临时表 drop table if exists #clients
结果校验
运行核心查询后,calculated_cumulative字段的计算值会与测试表中预置的desirable_result完全匹配:
- 客户1:1月1日累计10,1月2日累计30
- 客户2:1月1日累计20,1月2日累计40,1月3日累计60
- 客户3:1月1日累计20,1月2日累计50,1月4日累计70
注意事项
- 若同一客户在同一
date_tm时间点存在多条支付记录,需要在窗口排序规则中增加唯一业务标识(如交易流水ID),避免因排序优先级不确定导致的累计值偏差 - 该窗口函数写法在SQL Server 2017环境下的执行效率远高于传统自连接逐行累加的实现,百万级数据量下也能保持稳定的查询性能
内容的提问来源于stack exchange,提问作者Semyon-coder
相关产品推荐
相关产品推荐

