You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于各分类最新值的滚动求和实现及最大值查询方案咨询

基于集合的特殊滚动求和最大值实现方案

完全可以用窗口函数实现你要的逻辑,不需要游标或者递归CTE,性能远高于游标实现,具体方案如下:

核心思路

你要的滚动求和本质是同分类新金额替换旧金额,每笔交易对总和的影响可以拆解为增量:本次交易金额 - 该分类上一次的交易金额(首次出现的分类上一次金额为0)。按交易顺序累加所有增量,就能得到每笔交易完成后的总金额SumAmount,最后取最大值即可。

完整实现代码

CREATE PROCEDURE [dbo].[PriceHistory](@CustId int, @MaxPriceHistory decimal(16,2) Output)
AS
SET NOCOUNT ON;
WITH CategoryTranRank AS (
    -- 给每个分类的交易按时间+交易ID排序,避免同日交易顺序混乱
    SELECT 
        txn_id,
        CategoryID,
        amount,
        trans_date,
        ROW_NUMBER() OVER(PARTITION BY cust_id, CategoryID ORDER BY trans_date, txn_id) AS rn
    FROM mytable
    WHERE cust_id = @CustId
),
TranWithDiff AS (
    -- 计算每笔交易对应的总和增量
    SELECT 
        t1.txn_id,
        t1.trans_date,
        t1.amount - ISNULL(t2.amount, 0) AS sum_diff
    FROM CategoryTranRank t1
    LEFT JOIN CategoryTranRank t2 
        ON t1.CategoryID = t2.CategoryID 
        AND t2.rn = t1.rn - 1
),
RunningTotal AS (
    -- 累加增量得到每笔交易后的SumAmount
    SELECT 
        SUM(sum_diff) OVER(ORDER BY trans_date, txn_id ROWS UNBOUNDED PRECEDING) AS SumAmount
    FROM TranWithDiff
)
-- 取最大SumAmount作为输出
SELECT @MaxPriceHistory = MAX(SumAmount)
FROM RunningTotal;
GO

方案验证

你给出的示例数据代入运行后,得到的最大SumAmount为16,和你的预期结果、游标运行结果完全一致。如果需要同时输出每笔交易对应的SumAmount,直接将RunningTotal的查询结果和原表关联即可。

性能优势

相比游标实现,该方案基于SQL的集合运算特性,不需要逐行循环、临时表读写,在数据量较大时性能会有10倍以上的提升,且内存占用更低。


内容的提问来源于stack exchange,提问作者MrC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 13:24:04