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

基于单调递增行检查线程,需通过行偏移量实现计数器累加值

解决方案:计算带重置的计数器累加值

首先得明确需求核心:咱们有个计数器列val,遇到异常会重置为0,现在要新增一列记录从开始到当前行的所有有效计数累加总和,同时要求未发生重置的连续区间内,新列值和原val列当前值保持一致。这种带分段重置的累加需求,用窗口函数就能轻松解决,下面分步骤给你演示:

步骤1:给重置周期打分组标记

首先要把每次val=0的重置事件作为分界点,把数据分成一个个连续的计数周期。用SUM()窗口函数就能生成唯一的分组ID:

SELECT 
    id,
    val,
    -- 每碰到一次val=0,分组ID就加1,把后续数据归到新分组
    SUM(CASE WHEN val = 0 THEN 1 ELSE 0 END) OVER (ORDER BY id) AS group_id
FROM your_table;

举个例子,假设原始数据是:

idval
11
22
33
40
51
62
70
84

运行上面的语句后会得到分组结果:

idvalgroup_id
110
220
330
401
511
621
702
842

步骤2:计算全局累加值

接下来基于分组,先算出当前分组之前所有周期的总累加,再加上当前分组内的累计值,就能得到全局的累加列:

WITH grouped_data AS (
    SELECT 
        id,
        val,
        SUM(CASE WHEN val = 0 THEN 1 ELSE 0 END) OVER (ORDER BY id) AS group_id,
        -- 计算当前行之前所有非重置值的总和
        SUM(CASE WHEN val = 0 THEN 0 ELSE val END) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS previous_total
    FROM your_table
)
SELECT 
    id,
    val,
    -- 重置行直接取之前的总累加;非重置行则在之前总和基础上加当前分组的累计
    CASE 
        WHEN val = 0 THEN COALESCE(previous_total, 0)
        ELSE COALESCE(previous_total, 0) + SUM(val) OVER (PARTITION BY group_id ORDER BY id)
    END AS total_accum
FROM grouped_data;

最终得到的结果完全符合需求:

idvaltotal_accum
111
222
333
403
514
626
706
8410

额外说明

  • 必须保证数据有可靠的排序字段(比如id、时间戳),否则分组和累计逻辑会出错;
  • 如果只需要每个周期内的局部累计(不需要全局累加),可以简化成只计算分组内的累计值;
  • 不同SQL方言的窗口函数语法略有差异,但MySQL 8.0+、PostgreSQL、SQL Server都支持上述写法,老版本MySQL可以用变量实现类似逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:12:21