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

SQL查询需求:计算时间段内各数值区间的差值总和

用SQL实现数值区间差值总和计算

这个需求完全可以用单条SQL查询实现,而且基于集合的操作性能会比逐行遍历高效得多。我先拆解你的需求逻辑,再给出对应的查询语句:

需求逻辑拆解

从你的示例结果反推,你需要:

  • 把数据按0分割成多个区间:
    1. 第一个区间:从表的第一条记录到第一个0的前一条记录,计算区间最大值 - 区间起始值;
    2. 后续每个区间:从一个0之后到下一个0之前的记录,计算区间最大值 - 对应分割用的0的值;
  • 最后把所有区间的差值累加得到总和。

实现SQL(兼容MySQL8+、PostgreSQL、SQL Server等)

假设你的表名为value_log,我们用CTE和窗口函数来实现:

WITH grouped_data AS (
  SELECT 
    Value,
    Time,
    -- 按0分割组:每遇到一个0,组ID递增
    SUM(CASE WHEN Value = 0 THEN 1 ELSE 0 END) OVER (ORDER BY Time) AS group_id
  FROM value_log
),
group_start_values AS (
  SELECT
    group_id,
    -- 第一个组的起始值是组内第一条记录的值,其他组起始值为0(分割用的0)
    CASE 
      WHEN group_id = 0 THEN FIRST_VALUE(Value) OVER (PARTITION BY group_id ORDER BY Time)
      ELSE 0
    END AS start_value
  FROM grouped_data
),
group_max_values AS (
  SELECT
    group_id,
    -- 计算每个组内非0记录的最大值
    MAX(CASE WHEN Value != 0 THEN Value END) AS max_value
  FROM grouped_data
  GROUP BY group_id
)
-- 累加所有有效区间的差值(过滤掉只有0的无效组)
SELECT SUM(gm.max_value - gs.start_value) AS total_diff
FROM group_start_values gs
JOIN group_max_values gm ON gs.group_id = gm.group_id
WHERE gm.max_value IS NOT NULL;

逻辑验证(匹配你的示例数据)

针对你给出的示例数据:

  • group_id=0:包含5、6、7,start_value=5,max_value=7,差值为7-5=2;
  • group_id=1:包含0、1、2、3、4、5、6,start_value=0,max_value=6,差值为6-0=6;
  • group_id=2:只有0,max_value为NULL,被过滤;
    最终总和为2+6=8,完全匹配你的预期结果。

边界情况处理

这个查询还能自动处理以下场景:

  • 表的第一条记录就是0:第一个组会被过滤,后续区间正常计算;
  • 表的最后一条记录不是0:最后一个区间的差值会被正常累加;
  • 连续出现多个0:中间只包含0的组会被过滤,不影响结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:36:37