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

SQL如何合并用户连续日期记录获取各时间段起止日期

连续登录日期段合并实现方案

这个需求属于SQL经典的**Gaps and Islands(间断与区间)**问题,核心是识别同一用户下日期的断点,给连续的日期段打上统一分组标记后聚合即可,不需要写复杂的循环或者存储过程,用窗口函数就能高效实现。

核心实现思路

  • 对每个用户的登录记录按日期升序排序,生成连续行号
  • 用每条记录的登录日期减去对应行号的天数,生成分组标记:同一连续日期段内的所有记录,计算出的分组标记值完全相同,日期间断时标记值会发生跳变
  • 按用户账号+分组标记聚合,取分组内最小的date_start作为段起始、最大的date_end作为段结束,输出结果即可

可直接运行的代码示例

以下写法兼容MySQL 8.0+、PostgreSQL、Hive、Spark SQL等所有支持标准窗口函数的数据库:

WITH login_with_groupflag AS (
    SELECT
        login,
        date_start,
        date_end,
        DATE_SUB(
            date_start,
            INTERVAL ROW_NUMBER() OVER (PARTITION BY login ORDER BY date_start) DAY
        ) AS group_flag
    FROM your_login_table -- 替换成你的实际表名
)
SELECT
    login,
    MIN(date_start) AS date_start,
    MAX(date_end) AS date_end
FROM login_with_groupflag
GROUP BY login, group_flag
ORDER BY date_start;

针对你提供的样例数据,上述代码运行后会直接返回你期望的结果:

| login | date_start | date_end   |
|-------|------------|------------|
| user1 | 2022-01-01 | 2022-01-03 |
| user2 | 2022-01-05 | 2022-01-06 |
| user1 | 2022-02-24 | 2022-02-26 |

兼容场景说明

  • 如果你用的是不支持窗口函数的MySQL 5.x版本,可以用用户变量模拟行号计算,核心逻辑和上述方案完全一致,参考写法如下:
SELECT
    login,
    MIN(date_start) AS date_start,
    MAX(date_end) AS date_end
FROM (
    SELECT
        login,
        date_start,
        date_end,
        @row_num := IF(@current_login = login, @row_num + 1, 1) AS rn,
        @group_flag := DATE_SUB(date_start, INTERVAL @row_num DAY) AS group_flag,
        @current_login := login
    FROM (
        SELECT * FROM your_login_table ORDER BY login, date_start
    ) AS sorted_records,
    (SELECT @row_num := 0, @current_login := '', @group_flag := '') AS init_vars
) AS records_with_flag
GROUP BY login, group_flag
ORDER BY date_start;
  • 如果你的表中存在跨多日的登录段(即date_end大于date_start的记录),只需要把分组标记逻辑调整为「判断当前记录的起始日期和上一条记录的结束日期间隔是否超过1天,超过则标记为新分段起点,再通过累计求和生成分组ID」即可,核心思路不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:42:12