如何用ROW_NUMBER快速计算SQL表中连续登录天数,构造等差数列?

2026-04-27 17:380阅读0评论SEO资源
  • 内容介绍
  • 相关推荐

本文共计738个文字,预计阅读时间需要3分钟。

如何用ROW_NUMBER快速计算SQL表中连续登录天数,构造等差数列?

由于用户登录日期可能不连续、存在重复、跨月/跨年跳跃,使用`DATEDIFF()`函数计算天数差会将中间缺失的天数也计入,无法真实反映连续登录的情况。而使用`ROW_NUMBER()`按登录时间排序后生成的递增序号,与日期本身结合构成可排序序列,只要`login_date + ROW_NUMBER()`的结果相同,即可说明这些日期是连续的(即差分数列为1)。

关键点在于:同一连续段内,login_date - ROW_NUMBER() 是常量;段与段之间这个值会跳变。

构造分组标识:用 DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (...) DAY)

MySQL 8.0+ 或 PostgreSQL 中需把日期转为可运算类型。以 MySQL 为例,核心是构造一个稳定的“连续段锚点”:

SELECT user_id, login_date, DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) AS grp FROM user_login;

这个 grp 就是每个连续登录段的唯一标识。之后按 user_idgrp 分组,COUNT(*) 就是该段连续天数。

注意:ROW_NUMBER() 必须加 PARTITION BY user_id,否则全表编号会混掉不同用户;ORDER BY login_date 缺失会导致分组错乱。

阅读全文

本文共计738个文字,预计阅读时间需要3分钟。

如何用ROW_NUMBER快速计算SQL表中连续登录天数,构造等差数列?

由于用户登录日期可能不连续、存在重复、跨月/跨年跳跃,使用`DATEDIFF()`函数计算天数差会将中间缺失的天数也计入,无法真实反映连续登录的情况。而使用`ROW_NUMBER()`按登录时间排序后生成的递增序号,与日期本身结合构成可排序序列,只要`login_date + ROW_NUMBER()`的结果相同,即可说明这些日期是连续的(即差分数列为1)。

关键点在于:同一连续段内,login_date - ROW_NUMBER() 是常量;段与段之间这个值会跳变。

构造分组标识:用 DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (...) DAY)

MySQL 8.0+ 或 PostgreSQL 中需把日期转为可运算类型。以 MySQL 为例,核心是构造一个稳定的“连续段锚点”:

SELECT user_id, login_date, DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) AS grp FROM user_login;

这个 grp 就是每个连续登录段的唯一标识。之后按 user_idgrp 分组,COUNT(*) 就是该段连续天数。

注意:ROW_NUMBER() 必须加 PARTITION BY user_id,否则全表编号会混掉不同用户;ORDER BY login_date 缺失会导致分组错乱。

阅读全文