SQL面试题挑战07:间隔连续问题

本文介绍了如何通过SQL查询解决游戏公司用户登录数据中计算每个用户最大连续登录天数的问题,利用窗口函数、分组和条件判断实现,展示了如何利用DAG(有向无环图)逻辑进行处理。
摘要由CSDN通过智能技术生成

SQL面试题挑战07:间隔连续问题

问题

下面是某游戏公司记录的用户每日登录数据, 计算每个用户最大的连续登录天数,定义连续登录时可以间隔一天。举例:如果一个用户在 1,3,5,6,9 登录了游戏,则视为连续 6 天登录。

id          dt
1001    2021-12-12
1002    2021-12-12
1001    2021-12-13
1001    2021-12-14
1001    2021-12-16
1002    2021-12-16
1001    2021-12-19
1002    2021-12-17
1001    2021-12-20

建表语句

drop table if exists login;
create table login(
    id varchar(20),
    dt date
);
insert into login values
(1001, '2021-12-12'),
(1002, '2021-12-12'),
(1001, '2021-12-13'),
(1001, '2021-12-14'),
(1001, '2021-12-16'),
(1002, '2021-12-16'),
(1001, '2021-12-19'),
(1002, '2021-12-17'),
(1001, '2021-12-20')

解答

思路:

首先开窗按id分组按dt排序,然后获取前一行dt(默认值设一个很小的值),然后将dt和前一行dt求差,结果如下:

iddtdiff
10012021-12-128381
10012021-12-131
10012021-12-141
10012021-12-162
10012021-12-193
10012021-12-201
10022021-12-128381
10022021-12-164
10022021-12-171

可以发现如果diff大于2那么说明当前行和前面已经不连续了。为此我们可以diff来打标记,如果diff大于3那么就设置标记为1,否则为0,结果如下

iddtflag
10012021-12-121
10012021-12-130
10012021-12-140
10012021-12-160
10012021-12-191
10012021-12-200
10022021-12-121
10022021-12-161
10022021-12-170

可以看到flag中,1中间的行就是连续登录的天数。接着我们将flag累积求和,这样属于同一个连续登陆区间的flag值会相当,如下

idg
10011
10011
10011
10011
10012
10012
10021
10022
10022

然后我们按照id和g分组,统计行数即是登录天数。最后按照id分组,求取最大值即可。

完整查询如下

select 
    id,
    max(cnt)max_cnt
from
    (
       select
            id,
            count(*)cnt
        from
            (
                select
                    id,
                    sum(flag)over(partition by id order by dt)g
                from
                    (
                        select
                            id,
                            dt,
                            if(datediff(dt,lag(dt,1) over (partition by id order by dt))<=2,0,1)flag
                        from
                            login
                    )t0
            )t1
        group by
            id,
            g
    ) t2
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值