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

如何使用SQL从带间隔的数值列中提取各连续数值区间

SQL 提取连续数值区间实现方案

这是典型的SQL「岛屿问题」(连续序列分组需求),以下是通用实现方案:

前置假设

我们假定存储待处理数据的表名为num_table,数值列名为val,列中包含你给出的带null、有间隔的样例数据。

通用实现(兼容MySQL8.0+、PostgreSQL、SQL Server、Oracle等支持窗口函数的数据库)

WITH filtered_data AS (
    -- 过滤空值,同时给每行生成连续序号
    SELECT 
        val,
        ROW_NUMBER() OVER (ORDER BY val) AS rn
    FROM num_table
    WHERE val IS NOT NULL
)
-- 按差值分组,取每组最小/最大值即为连续区间首尾
SELECT
    MIN(val) AS 区间起始值,
    MAX(val) AS 区间结束值,
    CONCAT('区间', ROW_NUMBER() OVER (ORDER BY MIN(val)), ' - ', MIN(val), ' 至 ', MAX(val)) AS 区间展示文本
FROM filtered_data
GROUP BY (val - rn)
ORDER BY 区间起始值;

实现原理

核心逻辑利用了连续数值与连续行号的差值固定的特性:比如81、82、83对应的行号为1、2、3,val - rn的结果均为80,会被分到同一组;下一段连续序列的第一个值86对应的行号为4,86-4=82,和前一组差值不同,自动进入新分组。

低版本MySQL实现(不支持窗口函数场景)

如果使用的是MySQL5.x等不支持CTE和窗口函数的版本,可以用变量替代实现:

SELECT 
    MIN(val) AS 区间起始值,
    MAX(val) AS 区间结束值,
    CONCAT('区间', @group_idx := @group_idx + 1, ' - ', MIN(val), ' 至 ', MAX(val)) AS 区间展示文本
FROM (
    SELECT 
        val,
        @rn := @rn + 1,
        val - @rn AS group_flag
    FROM num_table, (SELECT @rn := 0, @group_idx := 0) AS init
    WHERE val IS NOT NULL
    ORDER BY val
) AS t
GROUP BY group_flag
ORDER BY 区间起始值;

运行结果

和你给出的预期输出完全一致:

区间起始值区间结束值区间展示文本
8183区间1 - 81 至 83
8689区间2 - 86 至 89
9597区间3 - 95 至 97

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:24:03