导读:本期聚焦于小伙伴创作的《SQL如何识别连续登录行为?窗口函数ROW_NUMBER与差值法怎么用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL如何识别连续登录行为?窗口函数ROW_NUMBER与差值法怎么用》有用,将其分享出去将是对创作者最好的鼓励。

识别用户连续登录行为是用户留存分析、活跃度统计场景下的常见需求,核心逻辑是通过用户的登录日期记录,判断相邻登录日期是否连续,进而统计连续登录的天数。下面介绍两种常用的SQL实现方案。

SQL如何识别连续登录行为?窗口函数ROW_NUMBER与差值法怎么用

基础数据准备

首先假设我们有用户登录记录表user_login_log,表结构如下:

字段名类型说明
user_idint用户ID
login_datedate登录日期

表中存在部分示例数据:

-- 示例数据插入语句
INSERT INTO user_login_log (user_id, login_date) VALUES
(1, '2024-01-01'),
(1, '2024-01-02'),
(1, '2024-01-03'),
(1, '2024-01-05'),
(2, '2024-01-01'),
(2, '2024-01-03'),
(2, '2024-01-04');

方案一:ROW_NUMBER窗口函数法

该方案的核心思路是,先对每个用户的登录日期按升序排序生成行号,再用登录日期减去行号对应的天数,如果连续登录,这个差值会保持一致。

实现步骤

  • 第一步:对每个用户的登录日期去重,避免同一天多次登录影响统计结果
  • 第二步:用ROW_NUMBER()窗口函数按用户分组、登录日期升序生成排序号
  • 第三步:计算登录日期减去排序号天数的差值,作为连续分组的标识
  • 第四步:按用户和差值分组,统计每个组的天数,即为连续登录天数

完整SQL代码

WITH distinct_login AS (
    -- 去重同一用户同一天的登录记录
    SELECT DISTINCT user_id, login_date
    FROM user_login_log
),
login_with_rn AS (
    SELECT 
        user_id,
        login_date,
        -- 按用户分组,登录日期升序生成行号
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS rn
    FROM distinct_login
),
login_group AS (
    SELECT 
        user_id,
        login_date,
        -- 登录日期减去行号天数,连续登录的差值相同
        DATE_SUB(login_date, INTERVAL rn DAY) AS group_flag
    FROM login_with_rn
)
-- 统计每个用户的连续登录天数
SELECT 
    user_id,
    MIN(login_date) AS start_login_date,
    MAX(login_date) AS end_login_date,
    COUNT(*) AS continuous_days
FROM login_group
GROUP BY user_id, group_flag
ORDER BY user_id, start_login_date;

上述代码执行后,会得到每个用户每段连续登录的起始日期、结束日期和连续天数,比如用户1会有两段连续登录记录,分别是1月1日到1月3日共3天,1月5日共1天。

方案二:差值法(LAG窗口函数版)

该方案不需要生成行号,而是通过LAG窗口函数获取用户上一次的登录日期,判断两次登录日期的差值是否为1天,来标记连续登录的起始点。

实现步骤

  • 第一步:同样先对用户的登录日期去重
  • 第二步:用LAG函数获取每个用户上一次的登录日期,计算当前登录日期和上一次登录日期的差值
  • 第三步:如果差值为1天,说明是连续登录,否则是当前连续段的起始点,给起始点标记分组ID
  • 第四步:按分组ID统计连续登录天数

完整SQL代码

WITH distinct_login AS (
    SELECT DISTINCT user_id, login_date
    FROM user_login_log
),
login_with_prev AS (
    SELECT 
        user_id,
        login_date,
        -- 获取上一次登录日期
        LAG(login_date) OVER (PARTITION BY user_id ORDER BY login_date) AS prev_login_date
    FROM distinct_login
),
login_mark AS (
    SELECT 
        user_id,
        login_date,
        -- 如果和上一次登录差1天,不属于新段,否则属于新段,用累计和生成分组ID
        SUM(CASE WHEN DATEDIFF(login_date, prev_login_date) = 1 THEN 0 ELSE 1 END) 
        OVER (PARTITION BY user_id ORDER BY login_date) AS group_id
    FROM login_with_prev
)
-- 统计连续登录天数
SELECT 
    user_id,
    MIN(login_date) AS start_login_date,
    MAX(login_date) AS end_login_date,
    COUNT(*) AS continuous_days
FROM login_mark
GROUP BY user_id, group_id
ORDER BY user_id, start_login_date;

两种方案对比

对比维度ROW_NUMBER法差值法(LAG版)
逻辑复杂度较低,依赖日期减行号的特性稍高,需要判断日期差值
适用场景所有支持窗口函数的数据库支持LAG函数的数据库
性能表现排序和差值计算开销较小需要额外计算日期差值,开销略高

实际使用中可以根据数据库支持的函数类型和业务需求选择合适的方案,两种方案都能准确识别用户的连续登录行为。

SQL窗口函数ROW_NUMBER连续登录差值法修改时间:2026-07-06 22:21:25

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。