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

MySQL按周序列中断分组:拆分连续区间统计需求

按周序列中断点分组统计连续周区间的SQL实现

问题背景

执行以下SQL查询项目资源推荐运行数据时,发现部分资源的周序列存在中断(例如resource_id_reassigned为103046779的记录中,2022-w34后直接跳到2022-w41):

select *
from rpt.project_resource_recommendation_runs pr
where pr.project_id = 'a004M00000VEdN3QAL' and pr.run_id = '202208021659477396' 

当前使用的统计SQL仅能获取每个资源ID的整体起止周,无法按周序列的中断点拆分出连续周区间:

select min(week_of_year),max(week_of_year) ,resource_id_reassigned
from rpt.project_resource_recommendation_runs pr
where pr.project_id = 'a004M00000VEdN3QAL' and pr.run_id = '202208021659477396' 
group by resource_id_reassigned 

期望输出按中断点拆分后的连续周区间统计结果:

2022-w31    2022-w34    103046779
2022-w35    2024-w26    103046779
2022-w35    2022-w40    106987979
2022-w32    2024-w20    1000
2022-w34    2024-w16    1005

解决方案

核心思路是为每个连续周区间生成唯一分组标识,通过窗口函数实现:

  1. 将week_of_year转换为可计算的数值(拆分年份和周数,计算为年份*52 + 周数),方便判断周连续性;
  2. 用LAG窗口函数获取同一资源的上一条记录的周数值;
  3. 对比当前周与上一周的差值,若差值不等于1则标记为新分组起点;
  4. 累计分组标识,最后按分组标识和资源ID分组,取每个分组的起止周。

完整SQL示例:

WITH processed_data AS (
    SELECT 
        resource_id_reassigned,
        week_of_year,
        -- 转换周字符串为可计算的数值
        CAST(SUBSTRING(week_of_year, 1, 4) AS INT)*52 + CAST(SUBSTRING(week_of_year, 6, 2) AS INT) AS week_num,
        -- 判断是否为新分组起点
        CASE 
            WHEN LAG(CAST(SUBSTRING(week_of_year, 1, 4) AS INT)*52 + CAST(SUBSTRING(week_of_year, 6, 2) AS INT)) 
                 OVER (PARTITION BY resource_id_reassigned ORDER BY week_of_year) 
                 = CAST(SUBSTRING(week_of_year, 1, 4) AS INT)*52 + CAST(SUBSTRING(week_of_year, 6, 2) AS INT) -1
            THEN 0
            ELSE 1
        END AS is_new_group
    FROM rpt.project_resource_recommendation_runs pr
    WHERE pr.project_id = 'a004M00000VEdN3QAL' and pr.run_id = '202208021659477396'
),
grouped_data AS (
    SELECT 
        resource_id_reassigned,
        week_of_year,
        -- 生成连续区间的分组ID
        SUM(is_new_group) OVER (PARTITION BY resource_id_reassigned ORDER BY week_of_year) AS group_id
    FROM processed_data
)
SELECT 
    MIN(week_of_year) AS start_week,
    MAX(week_of_year) AS end_week,
    resource_id_reassigned
FROM grouped_data
GROUP BY resource_id_reassigned, group_id
ORDER BY resource_id_reassigned, start_week;

补充说明

  • 若数据库支持日期解析函数(比如PostgreSQL的TO_DATE(week_of_year, 'IYYY-IW')),可替代手动字符串拆分,用日期差值判断连续性,结果更严谨;
  • PARTITION BY resource_id_reassigned确保仅在同一资源的记录内计算连续周;
  • ORDER BY week_of_year保证周序列排序正确,避免计算错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 01:06:39