一、题目
现有各用户的登录记录表zbj_login_events如下,表中每行数据表达的信息是一个用户何时登录了平台。 现要求统计各用户最长的连续登录天数,间断一天也算作连续,例如:一个用户在1,3,5,6登录,则视为连续4天登录。

二、思路
这是一个连续性问题,但是又一些新变化,间隔一天也算连续,所以只使用日期差值计算的方法就不能实现目标了,下面看一下具体实现步骤:
第一步:计算登录日期与登录次序的差值日期。

可以发现一个规律:如果连续登录则date_diff相同,如果登录日期相隔一天则date_diff也相隔一天,比如user_id:101的date_diff有2021-11-30和2021-12-01,那么这两个时间段相隔一天。
第二步:基于第1步的结果,如果相隔一天则date_diff是连续的,那么又变成了一个连续问题。首先对userid和date_diff,然后计算date_diff与次序的差值日期

第三步:计算用户连续登录总天数,包含间隔一天的情况

第四步:取每个用户连续登录最长的天数

三、解答
with tab_user_login_diff as (
-- 第一步:计算登录日期与登录次序的差值日期。
select
user_id,
log_date,
date_sub(log_date, rn) date_diff,
rn
from (
select
user_id,
log_date,
row_number() over(partition by user_id order by log_date) rn
from (
select
user_id,
date_format(login_datetime, 'yyyy-MM-dd') log_date
from zbj_login_events
group by user_id,
date_format(login_datetime, 'yyyy-MM-dd')
) t11
) t21
),
tab_res_detail as (
-- 第二步:基于第1步的结果,如果相隔一天则date_diff是连续的,那么又变成了一个连续问题。首先对userid和date_diff,然后计算date_diff与次序的差值日期
select
user_id,
date_diff,
date_sub(date_diff, rn) date_diff2,
day_cnt
from (
select
user_id,
date_diff,
day_cnt,
row_number() over(partition by user_id order by date_diff) rn
from (
select
user_id,
date_diff,
count(*) day_cnt
from tab_user_login_diff
group by user_id,
date_diff
) t11
) t21
)
select
-- 第四步:取每个用户连续登录最长的天数
user_id,
max(day_cnt) day_cnt
from (
-- 第三步:计算连续登录总天数,包含间隔一天的情况
select
user_id,
date_diff2,
sum(day_cnt) day_cnt
from tab_res_detail
group by user_id,
date_diff2
) t11
group by user_id结果:

数据
# 建表
--建表语句
create table if not exists zbj_login_events(
user_id int comment '用户id',
login_datetime string comment '登录时间'
)comment '直播间访问记录'
stored as parquet;
--数据插入
INSERT overwrite table zbj_login_events
VALUES (100, '2021-12-01 19:00:00'),
(100, '2021-12-01 19:30:00'),
(100, '2021-12-02 21:01:00'),
(100, '2021-12-03 11:01:00'),
(101, '2021-12-01 19:05:00'),
(101, '2021-12-01 21:05:00'),
(101, '2021-12-02 11:05:00'),
(101, '2021-12-03 21:05:00'),
(101, '2021-12-05 15:05:00'),
(101, '2021-12-06 19:05:00'),
(101, '2021-12-10 10:05:00'),
(102, '2021-12-01 19:55:00'),
(102, '2021-12-01 21:05:00'),
(102, '2021-12-02 21:57:00'),
(102, '2021-12-03 19:10:00'),
(104, '2021-12-04 21:57:00'),
(104, '2021-12-02 22:57:00'),
(105, '2021-12-01 10:01:00');注:题目获取自网络
评论