SQL:连续登陆N天问题的通用解答

连续登陆N天问题的通用解决方案



一、问题描述

  • 表结构:

    有一张用户登陆记录表,结构与参考数据如下图

在这里插入图片描述

  • 查询:

    最近一月内,连续登陆超过5天的用户

  • 条件1:

    每个用户,每天可以有0条或多条登陆记录

  • 条件2:

    最近一个月(或者最近30)内,任意时间段,连续登陆5天都可以; 不一定是最后5天,中间时段也可以;


二、数据准备

表结构如下图,也可直接下载文章附加的SQL脚本文件,生成数据表结构等,方便使用。

在这里插入图片描述

三、通用方案一:使用 ROW_NUMBER() 窗口函数

  1. 数据去重

    每用户一天最多保留一条记录,并把时间转换为日期方便后续操作
    在这里插入图片描述

  2. 排名

    使用row_number() over(partition by 用户id order by 登录日期) 进行排名

    在这里插入图片描述

  3. 判断是否连续
    在第二步的基础上,登陆时间 - 排名后(使用date_sub()函数),得到的结果是同一天,则说明是连续的;否则是不连续的。这里的排名,是个等差数列。

    例如:2024-08-01减去它对应的排序数1,就是2024-07-31;2024-08-02减去它对应的排序数字2,就是2024-08-01;2024-08-03减去它对应的排序数字3,就是2024-08-02;到目前为止该用户已经连续登录三天了。就是这个逻辑,我们可以使用 date_sub() 函数。

    在这里插入图片描述

  4. 获取结果
    对上一步的结果,分组聚合后过滤,得到想要的数据

    说明:如果需求是求出所有登陆中,任意连续的N天记录,则要删除之前步骤中的where子句;如果是最后n天的情况下,再加上过滤,减少原始数据量,提高性能。

    在这里插入图片描述

通用方案二:使用 LEAD() 窗口函数

大思路一样,只是和下面的行比较。不始上面的思路清楚。有很多步,是相同的,就不再一一做了。

感兴趣的友友们,可以试试。记得来这里炫一炫噢!

总结

水平、时间有限,不中之处,请条友们不吝赐教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bicijinlian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值