SQL练习题:连续登录5天的活跃用户

题目

写一个 SQL 查询, 找到活跃用户的 id 和 name.
活跃用户是指那些至少连续 5 天登录账户的用户.
返回的结果表按照 id 排序.

Accounts 表:
id 是该表主键.
该表包含账户 id 和账户的用户名.

idname
1Winston
7Jonathan

Logins 表:
该表无主键, 可能包含重复项.
该表包含登录用户的账户 id 和登录日期. 用户也许一天内登录多次.

idlogin_date
72020-05-30
12020-05-30
72020-05-31
72020-06-01
72020-06-02
72020-06-02
72020-06-03
12020-06-07
72020-06-10

结果表格式如下例所示:

idname
7Jonathan

id = 1 的用户 Winston 仅仅在不同的 2 天内登录了 2 次, 所以, Winston 不是活跃用户.
id = 7 的用户 Jonathon 在不同的 6 天内登录了 7 次, , 6 天中有 5 天是连续的, 所以, Jonathan 是活跃用户.


解法一 窗口函数lead +datediff

1)去重
因为登录表汇总了多个日期和id 号,同一天可能回登录多次,我们只需要一个登录日期。所以需要先group by id, login_date去重。
2)datediff +lead
再用lead(login_date,4)over()窗口函数查找往下第4个登录日期是否与当前日期相差4天,即连续5天。

select distinct t.id,a.name
from (
    select
    	id, 
    	login_date,
    	datediff(
        	lead(login_date, 4) over(partition by id order by login_date)
        	,login_date
        	) as diff   
    from logins
    group by id, login_date
    ) as t
left join accounts a using(id)
where t. diff = 4

解法二:自连接

logins自连接后,限制条件有:
1) id 相同;
2)日期相差0-4天。
最后找出符合条件的日期合计达到5个的id。

如下表所示,如果有连续登录5天,那么在diff列在0-4范围内的会有5行。
连续登录5天的情况:

datedate2diff
tt0
tt-11
tt-22
tt-33
tt-44

第二天没有登录的情况:

datedate2diff
tt0
tt-11
tt-33
tt-44
select distinct a.id,a.name
from (
        select a.id, a.login_date as ad, b.login_date as bd
        from logins a
        join logins b
        	on a.id = b.id and datediff(a.login_date,b.login_date) between 0 and 4
        group by a.id, a.login_date
        having count(distinct b.login_date) = 5) as t 
left join accounts a on a.id = t.id

来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/active-users

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值