MySQL双ID分组下连续周数统计问题求助
解决MySQL按双ID分组统计连续周数的问题
我来帮你搞定这个按ID和ID2分组统计连续周数的问题~你的需求是对每组(ID, ID2),统计日期列对应的连续周的数量,原代码的问题在于只固定处理了ID=1的情况,而且没有正确按双ID分组来重置连续计数的逻辑,下面给你两种可行的解决方案:
方案一:使用窗口函数(MySQL 8.0+)
这是最简洁直观的方法,利用ROW_NUMBER()窗口函数来标记连续周的分组:
SELECT ID, ID2, COUNT(*) AS `Consecutive Week` FROM ( SELECT ID, ID2, -- 核心逻辑:连续周的YEARWEEK与行号的差值固定 YEARWEEK(Date, 1) - ROW_NUMBER() OVER(PARTITION BY ID, ID2 ORDER BY YEARWEEK(Date, 1)) AS group_tag FROM tbl ) t GROUP BY ID, ID2, group_tag ORDER BY ID, ID2;
原理说明:
对于每组(ID, ID2)内的记录,我们按周数排序后:
- 连续的周,
YEARWEEK每次递增1,行号也递增1,两者的差值保持不变 - 如果周数中断(比如中间隔了一周),
YEARWEEK的增量会大于1,差值就会变化,形成新的分组标记
这样通过group_tag就能把连续的周归为一组,最后统计每组的行数就是连续周数,完全符合你的预期结果。
方案二:兼容低版本MySQL(无窗口函数)
如果你的MySQL版本低于8.0,没有窗口函数,可以用用户变量来实现:
SELECT ID, ID2, COUNT(*) AS `Consecutive Week` FROM ( SELECT ID, ID2, -- 跟踪分组标记:当ID/ID2变化或周数不连续时,更新分组标记 @group_tag := CASE WHEN @prev_id = ID AND @prev_id2 = ID2 AND YEARWEEK(Date,1) = @prev_yw + 1 THEN @group_tag ELSE @group_tag + 1 END AS group_tag, -- 更新变量为当前记录的值,供下一行判断使用 @prev_id := ID, @prev_id2 := ID2, @prev_yw := YEARWEEK(Date,1) FROM tbl, -- 初始化变量 (SELECT @prev_id := NULL, @prev_id2 := NULL, @prev_yw := NULL, @group_tag := 0) var_init -- 必须按ID、ID2、日期排序,保证判断逻辑正确 ORDER BY ID, ID2, Date ) t GROUP BY ID, ID2, group_tag ORDER BY ID, ID2;
原理说明:
通过变量跟踪上一条记录的ID、ID2和周数,每遍历一条记录就判断:
- 如果当前记录的ID、ID2和上一条相同,且周数是上一周的下一周,就沿用当前分组标记
- 否则,分组标记加1,形成新的连续组
最后同样通过分组统计得到连续周数。
内容的提问来源于stack exchange,提问作者Mojo Allmighty
相关产品推荐
相关产品推荐

