2025面试题目:mysql查询连续登录天数

题目内容:

一个数据表中,有两个字段:登录用户名,登录日期时间。现在要查询一个用户连续登录天数是多少,应该怎么查询?

被问到的当时,感觉应该是挺简单的需求,但是没有做过类似的开发,一时间想不到怎么做sql查询。后面研究了一下,发现挺简单的。

假设表结构如下

字段名类型
username VARCHAR
login_time DATETIME

 目标如下:

给定一个用户名,查询该用户最长一次连续登录的天数(如最近连续登录了3天,或今天没有登录则中断)。

思路说明:

  1. 先对每个登录日期去重并排序

  2. 使用 ROW_NUMBER() 给每行编号;

  3. 把“日期”和“行号”做差,得到同一个“连续段”的标识;

  4. 根据这个差值分组后 GROUP BY 即可得到每段连续天数;

  5. 最后只取“最近的一段”,看它有几天。

示例 SQL:

WITH user_logins AS (
    SELECT DISTINCT DATE(login_time) AS login_date
    FROM login_table
    WHERE username = 'alice'
),
numbered AS (
    SELECT 
        login_date,
        ROW_NUMBER() OVER (ORDER BY login_date) AS rn
    FROM user_logins
),
grouped AS (
    SELECT 
        login_date,
        DATE_SUB(login_date, INTERVAL rn DAY) AS grp_key
    FROM numbered
)
SELECT 
    COUNT(*) AS consecutive_days,
    MAX(login_date) AS last_day
FROM grouped
GROUP BY grp_key
ORDER BY last_day DESC
LIMIT 1;

核心逻辑就是:

登录日期 - 序号 = 分组标识

只要这个值一致,说明这些天是连续的。中断时,这个值就会变,从而实现分段。

举个例子

我们有如下用户登录记录(按日期去重并升序):

login_daterow_number
2024-06-25 1
2024-06-26 2
2024-06-27 3
2024-06-29 4
2024-06-30 5

row_number 是用 ROW_NUMBER() OVER (ORDER BY login_date) 生成的连续序号。 

然后进行做差(login_date - row_number

我们想找“连续登录的天数”,你可以这样理解:

  • 正常情况下,如果用户每天连续登录:

    • 登录日期 +1,行号也 +1 → 二者的差值不变

  • 但如果中断了某天没登录,差值就会发生跳变!

所以我们构造一个字段:

DATE_SUB(login_date, INTERVAL row_number DAY) AS grp_key

这个表达式的意思是:“用日期减去行号的天数”,我们看看结果👇:

 
login_daterow_numbergrp_key
2024-06-25 1 2024-06-24
2024-06-26 2 2024-06-24
2024-06-27 3 2024-06-24
2024-06-29 4 2024-06-25
2024-06-30 5 2024-06-25

你会发现:

  • 前三行的差值是一样的(2024-06-24)👉属于同一组

  • 后两行的差值是一样的(2024-06-25)👉属于另一组

现在每组都有相同的 grp_key,代表一段连续登录的记录了!

最后分组取取最大数量就好了。

 
 
posted on 2025-06-29 08:48  leaverk  阅读(116)  评论(0)    收藏  举报