hive连续登陆问题

问题描述
在数据仓库中存在这样一张表,记录了2019年所有用户在哪天登录了我司的网站或者app。数据如下:
表名:test2
字段:id string,pday string
hive连续登陆问题_第1张图片
需求:统计用户在本年中连续登录天数最大是几天?如:
用户A在7月1、2、3、4日连续登录了4天;6、7、8日连续3天;11、12连续2天。用户A的当年最大连续登录天数是4天
用户B在6月29日,6月30日,7月1日连续登录3天。用户B的当年最大连续登录天数是3天
需要的到的结果是这样的:

在这里插入图片描述
题目刨析
此题需要将连续的天数打上相同的标签进行聚合。得到连续天数数量之后,取到最大值。
可难点就是确定哪些天数是连续的,凭什么将连续的日期放在一起呢?
我的思路是这样的,我们需要两个辅助列。
第一列:将每个用户的登录日期从小到大排序
第二列:登录日期在当年是第几天
我们先将两个辅助列写出来,看看是什么效果:

select
id,
pday,
row_number() over(partition by id order by pday) as rn,
dayofyear(from_unixtime(unix_timestamp(pday,‘yyyyMMdd’),‘yyyy-MM-dd’)) as day_of_year
from
test2
order by id,rn;
hive连续登陆问题_第2张图片
细心的同学可能已经发现了,若将两个辅助列做差,连续登录和非连续登录的天数就展现出区别了。如:
对于A用户来说
182-1=181
183-2=181
184-3=181
185-4=181
187-5=182
188-6=182
189-7=182
192-8=184
193-9=184
差值都是181的就是连续登录了4天,差值为182的为连续登录3天
为什么中间会断开呢。就是因为在20190705这一天用户没有登录,所以连续登录断掉了
接下来的事就容易多了。

解答
有了之前的刨析,直接看到这个答案应该就很容易接受了。语言苍白无力,还是直接看代码吧

select
id,
max(continuation_days) as max_continuation_days
from
(select
id,
count(*) as continuation_days
from
(select
id,
dayofyear(from_unixtime(unix_timestamp(pday,‘yyyyMMdd’),‘yyyy-MM-dd’))
-row_number() over(partition by id order by pday) as sub
from
test2
)t0
group by id,sub
)t0
group by id

结语:
当然也可以用date_sub(登陆日期,rank)进行group by
即如下sql:

select
id,
max(continuation_days) as max_continuation_days
from
(select
id,
count(*) as continuation_days
from
(select
id,
date_sub(from_unixtime(unix_timestamp(pday,‘yyyyMMdd’),‘yyyy-MM-dd’)
,row_number() over(partition by id order by pday) as sub
from
test2
)t0
group by id,sub
)t0
group by id

你可能感兴趣的:(hive,连续登录)