当前位置: 首页
数据库
SQL分组查询连续登录超3天用户

SQL分组查询连续登录超3天用户

热心网友 时间:2026-07-07
转载

利用ROW_NUMBER()对登录日期按用户分组排序编号,日期减去编号得到连续段锚点,再按用户和锚点分组统计天数,即可筛选出连续登录超过3天的用户。需注意日期格式统一、去重同一天多次登录,并为user_id和login_date建立联合索引以优化性能。

处理连续登录问题,核心思路其实就一句话:用`ROW_NUMBER()`给登录日期编号,再拿日期减去这个编号。你会发现,同一个连续段里,减出来的结果完全一致。比如,如果某用户在2024-01-01、01-02、01-03都有登录记录,编号分别是1、2、3,那么用日期分别减去对应编号,都会得到2023-12-31——这个共同的结果,就是连续段的“锚点”,也是我们分组判断的依据。 这里有三个细节值得留意: * `ROW_NUMBER()`必须按`user_id`分组、并按`login_date`排序,否则编号顺序会全乱套。 * 日期字段的格式要统一。如果`login_date`是`DATETIME`类型、带有时分秒,得先通过`CAST(login_date AS DATE)`把它转成纯日期,不然计算会出问题。 * MySQL 8.0+、PostgreSQL、SQL Server这些主流数据库都原生支持`ROW_NUMBER()`;但如果你还在用MySQL 5.7或更早版本,就只得用变量来模拟了——不仅容易出错,还影响性能,建议尽快升级或者换方案。 得到锚点列(通常命名为`grp`或`group_id`),接下来的操作就很直观了:对`user_id`和`grp`做联合分组,然后用`COUNT(*)`统计每组的天数。 一个典型的SQL写法如下:
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 login_log
) t
GROUP BY user_id, grp
HA VING COUNT(*) > 3;
注意一下`HA VING`条件:`COUNT(*) > 3`表示“超过3天”,也就是至少连续登录4天;如果需要“大于等于3天”,那么把`> 3`改成`>= 3`就行。 ### 重复登录与跨年边界的处理方式 用户同一天多次登录是一个常见陷阱——如果不处理,`COUNT(*)`的结果会偏大,导致统计失真。解决办法是:在子查询里先用`DISTINCT user_id, login_date`去重,或者用`GROUP BY user_id, login_date`预聚合一下。 至于跨年,其实不是什么大问题。`DATE_SUB`函数在MySQL里能正确处理,比如`2023-12-31 - INTERVAL 1 DAY = 2023-12-30`,不会有边界问题。但如果你用的是Oracle或PostgreSQL,日期运算的语法会有所不同:PostgreSQL需要写成`login_date - ROW_NUMBER() OVER (...)::INT`,Oracle则用`login_date - ROW_NUMBER() OVER (...)`。 ### 性能优化的关键:一个恰当的联合索引 如果没有合适的索引,`PARTITION BY user_id ORDER BY login_date`这类操作在百万级数据上几乎必然导致全表扫描,速度会非常慢。 解决方案很明确:建立一个覆盖`user_id`和`login_date`的联合索引。
CREATE INDEX idx_user_login ON login_log (user_id, login_date);
这个索引能同时支撑分组、排序和去重,比两个单列索引的组合有效得多。如果你的表已经有主键包含了这两列,请确认一下列的顺序是否一致——`user_id`必须在前。 连续登录分析本身不复杂,真正的难点往往在数据质量上。空值、时区混杂、日志漏采,任何一个问题都可能让锚点计算失准。上线之前,一定记得用真实的样本数据把中间结果跑一遍验证一下。
来源:https://www.php.cn/faq/2755843.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
SQL数据库视图简化开发人员编码的实用方法

SQL数据库视图简化开发人员编码的实用方法

视图适合封装固定逻辑(如固定时间窗口、静态状态过滤)和固定JOIN关系,不宜用于需动态传入参数(如用户ID、日期范围)的查询。视图性能取决于底层索引,而非视图本身。ALTERVIEW仅更新元数据,会短暂阻塞新查询启动,应避开高峰期操作。

时间:2026-07-18 22:24
MySQL decimal使用常见问题及解决方法

MySQL decimal使用常见问题及解决方法

MySQL中的DECIMAL类型用于精确数值计算,通过DECIMAL(M,D)定义精度与标度。常见问题包括精度设置不当导致溢出、计算时精度溢出、插入格式错误等。优化建议:合理设置M和D,可用BIGINT存储分单位,关键列建索引,保持版本更新。

时间:2026-07-18 22:22
MySQL大字段TEXT建立索引导致的性能下降解决方案

MySQL大字段TEXT建立索引导致的性能下降解决方案

TEXT字段无法直接建立常规B+树索引,前缀索引不支持左模糊查询,全文索引受词长、中文分词和更新延迟限制。高效替代方案是使用MD5摘要索引和垂直拆分,将TEXT字段分离到独立表,主表采用DYNAMIC行格式,避免溢出页IO问题。

时间:2026-07-18 22:22
金仓数据库迁移避坑指南:从未被质疑的左连接隐患

金仓数据库迁移避坑指南:从未被质疑的左连接隐患

迁移至金仓KES时,LEFTJOIN若在WHERE中过滤右表非空列,将会触发外连接消除,导致数据结果减少。正确做法是将过滤条件置于ON子句中。金仓KES与主流数据库行为一致,务必通过EXPLAIN仔细检查执行计划,以确保连接语义正确。

时间:2026-07-18 22:22
PostgreSQL与MySQL数据库日志机制深度对比

PostgreSQL与MySQL数据库日志机制深度对比

PostgreSQL仅使用一套WAL日志,就同时实现了MySQL的redo、binlog和undo的全部功能,而MySQL因插件式架构需要三套日志并依赖两阶段提交保证一致性。其多版本并发控制通过追加写实现,无需单独的undo日志,但需要定期执行VACUUM操作清理死元组,防止表膨胀。

时间:2026-07-18 22:22
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜