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

如何用SQL实现带0下限限制的SUM()窗口函数?

实现带下限的累加列(SUM_FUNC_LIMIT)的SQL方案

要生成满足「累加结果小于0则取0,否则保留累加值」的SUM_FUNC_LIMIT列,由于该逻辑依赖前一行的计算结果,普通SUM()窗口函数无法直接实现,以下是两种通用解决方案:

方案一:递归CTE(适用于MySQL 8.0+、PostgreSQL、SQL Server等支持递归的数据库)

假设你的表名为your_table,包含ROW(行号,注意是关键字需用反引号包裹)和AMOUNT列,递归CTE可以逐行计算带限制的累加值:

WITH RECURSIVE cte AS (
    -- 初始化第一行数据
    SELECT 
        `ROW`,
        AMOUNT,
        SUM(AMOUNT) OVER (ORDER BY `ROW`) AS SUM_FUNC,
        GREATEST(AMOUNT, 0) AS SUM_FUNC_LIMIT
    FROM your_table
    WHERE `ROW` = 1

    UNION ALL

    -- 递归计算后续行
    SELECT 
        t.`ROW`,
        t.AMOUNT,
        c.SUM_FUNC + t.AMOUNT AS SUM_FUNC,
        GREATEST(c.SUM_FUNC_LIMIT + t.AMOUNT, 0) AS SUM_FUNC_LIMIT
    FROM your_table t
    JOIN cte c ON t.`ROW` = c.`ROW` + 1
)
SELECT * FROM cte ORDER BY `ROW`;

逻辑说明:

  • 初始行取表中第一行数据,SUM_FUNC_LIMIT直接取金额与0的最大值
  • 后续行通过关联前一行的递归结果,计算新的累加值后再与0取最大,实现带限制的累加逻辑

方案二:用户变量(适用于MySQL 5.x等不支持递归CTE的老版本数据库)

利用用户变量保存前一行的计算结果,逐行迭代更新:

SELECT 
    `ROW`,
    AMOUNT,
    @sum_func := @sum_func + AMOUNT AS SUM_FUNC,
    @sum_limit := GREATEST(@sum_limit + AMOUNT, 0) AS SUM_FUNC_LIMIT
FROM your_table,
(SELECT @sum_func := 0, @sum_limit := 0) AS init
ORDER BY `ROW`;

逻辑说明:

  • 初始化两个变量@sum_func和@sum_limit分别保存普通累加和带限累加的前一行结果
  • 按行号排序后,逐行更新变量值,GREATEST()函数实现小于0取0的限制

以你提到的示例验证:

  • 行5金额为-6时,若前一行SUM_FUNC_LIMIT为2,计算得2 + (-6) = -4,取0作为当前行的SUM_FUNC_LIMIT
  • 行6金额为3时,0 + 3 = 3,直接保留3作为当前行的SUM_FUNC_LIMIT

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:05:13