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

MySQL实现按供应商分组重置的累计求和(Running Total)问题咨询

分组累计Paid值实现方案

你原来的写法只维护了全局累计变量,没有对Vendor做变更判断,因此跨供应商时不会重置累计值。你可以根据你的MySQL版本选择以下两种实现方式:

方案1:MySQL 8.0及以上版本(推荐,窗口函数实现)

直接用开窗函数自带的分区逻辑即可实现分组内累计,性能和稳定性都优于变量写法:

SELECT 
    InvYear,
    InvQuarter,
    InvDesc1,
    InvDesc2,
    Vendor,
    Paid,
    Billed,
    SUM(Paid) OVER (
        PARTITION BY Vendor 
        ORDER BY InvYear, InvQuarter, InvDesc1, InvDesc2
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS Paid_cum
FROM Vendor;

逻辑说明:

  • PARTITION BY Vendor:按Vendor字段分组,每个分组单独计算累计值
  • ORDER BY:指定分组内的累计顺序,你可以根据业务需求调整排序规则
  • ROWS BETWEEN ...:明确累计范围为分组内第一行到当前行,避免窗口默认规则带来的统计偏差

方案2:MySQL 5.x及更低版本(兼容用户变量实现)

如果你的数据库版本不支持窗口函数,可以调整原变量写法,新增变量记录上一行的Vendor值,遇到Vendor变更时自动重置累计:

-- 初始化累计变量和上一个Vendor记录变量
SET @cum := 0, @prev_vendor := '';
SELECT 
    InvYear,
    InvQuarter,
    InvDesc1,
    InvDesc2,
    Vendor,
    Paid,
    Billed,
    @cum := IF(Vendor = @prev_vendor, @cum + Paid, Paid) AS Paid_cum,
    @prev_vendor := Vendor -- 更新上一个Vendor值供下一行判断,不需要该字段可嵌套外层查询过滤
FROM Vendor
-- 必须先按Vendor排序,保证同供应商的行连续排列,否则变量判断会出错
ORDER BY Vendor, InvYear, InvQuarter, InvDesc1, InvDesc2;

如果不需要显示@prev_vendor := Vendor这列,可以在外层再嵌套一层查询,只保留需要的字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:15:08