TSQL实现按客户统计含当月近3个月Qty总和查询
问题原因
你原有查询的逻辑缺陷在于:仅为每行数据计算了自身对应的前2个月起始日期,没有建立「统计月份」和「符合时间范围的所有历史销售记录」的关联关系,最终WHERE条件永远成立(每行的Sale_Month必然在自身的last_two_Months和自身之间),返回的只是单月的Qty合计,无法实现跨3个月的累加计算。
同时原有逻辑没有提前合并同客户同月份的多条记录,后续关联容易出现重复计算问题。
正确实现方案
采用「先单月聚合、再范围关联求和」的写法,完全适配月份不连续、同月份多条记录的业务场景,逻辑如下:
- 先按客户、销售月份分组,聚合得到每个客户每个自然月的总销量,同时完成月份去重,避免后续关联重复计算
- 将单月聚合结果自关联,匹配同客户下,销售日期落在「统计月份往前推2个自然月」到「统计月份」闭区间内的所有月份记录
- 按统计维度(客户、统计月份)分组,对匹配到的所有月份销量求和,得到滚动3个月的总Qty
WITH MonthlyAgg AS ( -- 第一步:聚合单月销量,去重同月份多条记录 SELECT Client, Sale_Month, SUM(Qty) AS SingleMonthQty FROM #temp_Sales GROUP BY Client, Sale_Month ) SELECT stat.Client, stat.Sale_Month, SUM(match.SingleMonthQty) AS TotalQty_3Months FROM MonthlyAgg stat INNER JOIN MonthlyAgg match ON stat.Client = match.Client -- 匹配近3个自然月的范围 AND match.Sale_Month BETWEEN DATEADD(MONTH, -2, stat.Sale_Month) AND stat.Sale_Month GROUP BY stat.Client, stat.Sale_Month ORDER BY stat.Client, stat.Sale_Month
结果验证
按照业务计算规则校验返回结果:
- 客户AAAA、2022-06-01的统计值:匹配到2022-04(5)、2022-05(10+2=12)、2022-06(5),合计22,符合预期
- 客户BBBB、2022-03-01的统计值:匹配到2022-01(6)、2022-03(6+10=16),合计22,符合预期
注:如果使用SQL Server 2022及以上版本,也可以用
DATE_BUCKET统一日期粒度后配合窗口函数计算,但上述自关联写法兼容性更好,所有支持TSQL的版本均可运行,且无需额外补全连续日期序列,适配月份不连续的场景。
内容的提问来源于stack exchange,提问作者Melvin
相关产品推荐
相关产品推荐

