SQL如何统计连续达标的月份_ROW_NUMBER与日期关联算法

来源:站长站作者:狼行天下头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQL如何统计连续达标的月份_ROW_NUMBER与日期关联算法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL如何统计连续达标的月份_ROW_NUMBER与日期关联算法》有用,将其分享出去将是对创作者最好的鼓励。

在业务数据统计工作中,经常需要统计某个主体连续达标的月份数量,比如统计连续3个月销售额超过10万的门店,或者连续6个月能耗低于阈值的设备。这类需求如果直接用分组统计很难实现,结合ROW_NUMBER窗口函数和日期关联算法可以轻松解决。

SQL如何统计连续达标的月份_ROW_NUMBER与日期关联算法

核心实现思路

连续达标统计的核心逻辑是:先筛选出所有达标的月份记录,然后对每个主体的达标月份排序,用达标月份减去排序序号得到同一个连续区间的标识值,最后对标识值分组统计数量即可。

这里用到的两个关键技术点分别是:

  • ROW_NUMBER窗口函数:为每个主体的达标月份生成连续的序号,序号从1开始递增
  • 日期关联算法:通过月份日期和ROW_NUMBER序号的差值,判断是否属于同一个连续区间

具体实现示例

场景说明

假设我们有门店销售记录表store_sales,表结构如下:

字段名类型说明
store_idint门店ID
sale_monthdate销售月份,格式为YYYY-MM-01
sale_amountdecimal当月销售额

需求是统计每个门店连续销售额超过10万的月份数量,以及对应的连续区间起始和结束月份。

实现步骤

第一步:筛选达标月份

先筛选出所有销售额超过10万的记录,作为后续统计的基础数据。

-- 筛选达标月份
SELECT 
    store_id,
    sale_month,
    sale_amount
FROM store_sales
WHERE sale_amount > 100000

第二步:生成ROW_NUMBER序号

对每个门店的达标月份按时间升序生成ROW_NUMBER序号,序号从1开始递增。

-- 生成序号
SELECT 
    store_id,
    sale_month,
    sale_amount,
    ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY sale_month) AS rn
FROM (
    -- 筛选达标月份
    SELECT 
        store_id,
        sale_month,
        sale_amount
    FROM store_sales
    WHERE sale_amount > 100000
) t1

第三步:计算连续区间标识

用达标月份减去序号对应的月份间隔,同一个连续区间的记录会得到相同的标识值。这里需要将日期转换为月份数来计算差值,比如2023-01-01对应月份数为2023*12+1=24277,2023-02-01对应24278,以此类推。

-- 计算连续区间标识
SELECT 
    store_id,
    sale_month,
    sale_amount,
    rn,
    -- 将日期转换为月份数,减去序号得到连续区间标识
    (YEAR(sale_month) * 12 + MONTH(sale_month)) - rn AS continuous_flag
FROM (
    -- 生成序号
    SELECT 
        store_id,
        sale_month,
        sale_amount,
        ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY sale_month) AS rn
    FROM (
        -- 筛选达标月份
        SELECT 
            store_id,
            sale_month,
            sale_amount
        FROM store_sales
        WHERE sale_amount > 100000
    ) t1
) t2

第四步:分组统计连续达标情况

对store_id和continuous_flag分组,统计每个连续区间的月份数量、起始月份和结束月份。

-- 最终统计结果
SELECT 
    store_id,
    MIN(sale_month) AS start_month,
    MAX(sale_month) AS end_month,
    COUNT(*) AS continuous_month_count
FROM (
    -- 计算连续区间标识
    SELECT 
        store_id,
        sale_month,
        sale_amount,
        rn,
        (YEAR(sale_month) * 12 + MONTH(sale_month)) - rn AS continuous_flag
    FROM (
        -- 生成序号
        SELECT 
            store_id,
            sale_month,
            sale_amount,
            ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY sale_month) AS rn
        FROM (
            -- 筛选达标月份
            SELECT 
                store_id,
                sale_month,
                sale_amount
            FROM store_sales
            WHERE sale_amount > 100000
        ) t1
    ) t2
) t3
GROUP BY store_id, continuous_flag
ORDER BY store_id, start_month

算法原理说明

为什么用月份数减去ROW_NUMBER序号就能得到连续区间标识?我们可以举个例子:

假设某个门店的达标月份分别是2023-01、2023-02、2023-03、2023-05、2023-06:

  • 2023-01对应月份数24277,ROW_NUMBER是1,差值为24276
  • 2023-02对应月份数24278,ROW_NUMBER是2,差值为24276
  • 2023-03对应月份数24279,ROW_NUMBER是3,差值为24276
  • 2023-05对应月份数24281,ROW_NUMBER是4,差值为24277
  • 2023-06对应月份数24282,ROW_NUMBER是5,差值为24277

可以看到连续的三个月份差值相同,断开后的月份差值发生了变化,这样就能通过分组统计出每个连续区间的长度。

注意事项

  • 日期计算时要确保sale_month是当月的第一天,避免月份计算错误
  • 如果达标月份存在重复记录,需要先去重再进行计算
  • 不同数据库的日期函数可能有差异,上述示例基于MySQL,其他数据库可调整日期转月份数的逻辑
这种方法的性能表现较好,即使数据量较大,只要对store_id和sale_month建立联合索引,查询效率也能得到保障。

SQLROW_NUMBER连续达标月份日期关联算法修改时间:2026-07-06 03:36:25

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。