MsSql

关注公众号 jb51net

关闭
首页 > 数据库 > MsSql > sql连续N天登录用户

SQL语句查询连续N天登录用户(解决方案)

作者:白话说数

本文给大家介绍SQL语句查询连续N天登录用户,本文通过场景分析结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

前几天刷手机时看到一道有趣的 SQL 题:查询连续 3 天登录的用户。这让我联想到之前讨论过的开窗函数,深入思考后发现其实还有多种实现方式。今天就来和大家分享几种解决方案,欢迎一起讨论!

一、建表:还原场景问题

1.创建用户登录记录表t_login_records,包含用户 ID 和登录日期两个核心字段

DROP TABLE IF EXISTS t_login_records;#若表存在删除
-- 创建用户登录记录表
CREATE TABLE t_login_records (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    login_date DATE NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户登录记录表';

2.插入测试数据

-- 查看表结构	
DESC t_login_records;

INSERT INTO t_login_records (user_id, login_date) VALUES
(1, '2023-01-01'),
(1, '2023-01-02'),
(1, '2023-01-03'),  -- 用户1连续3天登录
(1, '2023-01-05'),
(2, '2023-01-01'),
(2, '2023-01-02'),
(2, '2023-01-04'),  -- 用户2不连续
(3, '2023-01-01'),
(3, '2023-01-02'),
(3, '2023-01-03'),  -- 用户3连续3天登录
(3, '2023-01-04'),  -- 用户3连续4天登录
(4, '2023-01-01'),
(4, '2023-01-03'),
(4, '2023-01-05'),  -- 用户4不连续    
(5, '2023-01-01'),
(5, '2023-01-02'),
(5, '2023-01-03'),  -- 用户5连续3天登录
(5, '2023-01-04'),  -- 用户5连续4天登录
(5, '2023-01-05'),	-- 用户5连续5天登录
(5, '2023-02-01'),	-- 断开
(5, '2023-02-02'),  -- 用户5再连续2天登录
(5, '2023-02-03');  -- 用户5再连续3天登录
SELECT * FROM t_login_records;

二、查询:多种方法实现

1.自连接查询

-- 方法1:自连接查询
SELECT DISTINCT t1.user_id
FROM t_login_records t1
JOIN t_login_records t2 
  ON t1.user_id = t2.user_id 
  AND DATEDIFF(t2.login_date, t1.login_date) = 1
JOIN t_login_records t3 
  ON t1.user_id = t3.user_id 
  AND DATEDIFF(t3.login_date, t1.login_date) = 2;

2.窗口函数

-- 方法2:窗口函数(适用于支持LEAD函数的数据库,如MySQL 8.0+、PostgreSQL)
SELECT DISTINCT user_id
FROM (
  SELECT 
    user_id,
    login_date,
    LEAD(login_date, 1) OVER (PARTITION BY user_id ORDER BY login_date) AS next_day,
    LEAD(login_date, 2) OVER (PARTITION BY user_id ORDER BY login_date) AS next_2_days
  FROM t_login_records
) t
WHERE DATEDIFF(next_day, login_date) = 1 
  AND DATEDIFF(next_2_days, login_date) = 2;

不满足条件,用户4未被选中。

3.日期差值分组

-- 方法3:日期差值分组(适用于支持ROW_NUMBER的数据库)
SELECT user_id
FROM (
  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 t_login_records
) t
GROUP BY user_id, grp
HAVING COUNT(DISTINCT login_date) >= 3;

三、总结:三种方法对比与拓展

方法优点缺点
自连接简单直接,兼容性强性能差(多次扫描表)
窗口函数逻辑清晰,一步到位需数据库支持窗口函数
日期差值性能最优,逻辑巧妙理解难度较高

这道题虽然仅要求查询连续 3 天登录的用户,但通过这三种方法我们可以举一反三。如果要查询连续 4 天、5 天甚至 N 天登录的用户,第三种日期差值分组法更具优势,只需修改 HAVING COUNT(DISTINCT login_date) >= N 即可实现 “一力破万法” 的效果!

到此这篇关于SQL语句查询连续N天登录用户的文章就介绍到这了,更多相关sql连续N天登录用户内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文