SQL 如何统计连续登录天数?

11次阅读

统计连续登录天数的核心思路是将“连续”转化为“日期差等于行号差”,通过按用户和差值分组计数识别连续区间,再取最大长度;需确保日期类型正确、去重,并适配不同数据库语法。

SQL 如何统计连续登录天数?

统计连续登录天数的核心思路是:把“连续”转化为“日期差等于行号差”,再通过分组识别每一段连续区间,最后取最大长度。

用日期和行号构造连续标识

对每个用户的登录记录按日期排序,生成行号(row_number),再用登录日期减去行号。同一段连续登录中,这个差值是固定的——因为日期每天+1,行号也每天+1,差值恒定。

  • 例如:用户在 2024-01-01、01-02、01-03 登录,对应行号 1/2/3,则 date – row_number 都是 2023-12-31
  • 只要这个差值相同,就属于同一连续段

按用户和差值分组计数

以 user_id 和上述计算出的差值(记为 group_key)为联合分组依据,统计每组的记录数,即为该连续段的天数。

select user_id, count(*) AS consecutive_days
  FROM (
    SELECT user_id, login_date,
        login_date – INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY AS group_key
    FROM login_log
  ) t
  GROUP BY user_id, group_key
  ORDER BY consecutive_days DESC;

获取每个用户的最长连续天数

在外层再套一层聚合,取每个 user_id 对应的最大 consecutive_days 即可。

  • 加一句:SELECT user_id, MAX(consecutive_days) AS max_consecutive FROM (…) GROUP BY user_id
  • 若只需全局最高纪录(比如谁连续登录最久),可去掉 GROUP BY,直接用 MAX()

注意点和常见坑

实际使用时需留意数据质量和边界情况:

  • 确保 login_date 是 DATE 类型,不是 DATETIME;否则需先用 DATE() 截取日期部分
  • 同一天多次登录要先去重,否则会干扰行号和连续性判断
  • 不同数据库语法略有差异:PostgreSQL 用 login_date – (ROW_NUMBER() – 1),SQL Server 推荐用 DATEADD(day, -ROW_NUMBER()+1, login_date)
text=ZqhQzanResources