Hive计算最大连续登陆天数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive计算最大连续登陆天数相关的知识,希望对你有一定的参考价值。
参考技术A强哥说他发现了财富密码,最近搞了一套股票算法,其中有一点涉及到股票连续涨停天数的计算方法,我们都知道股票周末是不开市的,这里有个断层,需要一点技巧。我问是不是时间序列,他说我瞎扯,我也知道自己是瞎扯。 问他方法,他竟然不告诉我,这么多年的兄弟情谊算个屁 。真当我没他聪明吗,哼!
靠人不如靠自己,我决定连夜研究一下在 Hive 里面计算最大连续天数的计算方法。
在网站平台类业务需求中用户的「最大登陆天数」,需求比较普遍。
原始数据:
说明 :数据是简化版,两列分别是user_id,log_in_date。现实情况需要从采集数据经过去重,转换得到以上形式数据。
我们先建表并且将数据导入 Hive :
查看一下数据:
核心是按访问时间排序,登陆时间列减去排序后的序列号,得到一个日期值,按这个值分组计数即可。
按照 user_id 分组,并且按照日期 log_in_date 排序:
结果:
这里可以看出, u0001 这个用户最大连续登录天数是4天,使用后面计算方法计算后可以验证。
可以看出规律,日期小的,行号也小;如果将日期跟行号做差值,连续登录的差值应该是一样的。
结果:
显然可以看出,最大连续连续登录是4次。
结果:
已经算出了,每个用户连续登录天数序列,接下取每个用户最大登录天数最大值即可:
结果跟我们的预期是一致的,用户 u0001 最大登录天数是4。
我们知道股票市场,比如咱们的A股,周末是不开盘的,那么一只股票如果上周五涨停,本周一接着涨停,这算是连续2天涨停,使用上面这种方法是不行的,使用 lead 函数试试:
结果
哈哈,是不是有思路了。
思路 :上面结果一共有3列,第一列是 uid ,通过 lead 函数,后面两列都是日期,那么两列日期都取值 周一 到 周五 之间,也就是说数据里面只有工作日日期,没有周末的数据,可以提前过滤使得数据满足,既然要连续,那么:
以上两种条件综合,就能计算出股票的 最大连续涨停天数 了,你学废了吗。
猜你喜欢
HDFS的快照讲解
Hadoop 数据迁移用法详解
Hbase修复工具Hbck
数仓建模分层理论
一文搞懂Hive的数据存储与压缩
大数据组件重点学习这几个
hive之连续登录问题
目录
问题
登陆日志,计算每个人连续登陆的最大天数!(注意:断一天也算连续)
数据如下所示:
id dt
01 2021-02-28
01 2021-03-01
01 2021-03-02
01 2021-03-04
01 2021-03-05
01 2021-03-06
01 2021-03-08
02 2021-03-01
02 2021-03-02
02 2021-03-03
02 2021-03-06
03 2021-03-06
方法1
思路:等差数列
1、按照id分组同时按照dt排序,求rk
2、将每行日期减去rk值得到flag标志,如果之前是连续的日期,则相减后为相同的日期,flag相同
3、按照id和flag分组,计算count(*)得数连续的天数
4、按照id分组同时按照flag排序,求rk
5、将每行flag减去rk值得到new_flag标志
6、按照id和new_flag分组,计算连续的天数
7、对id进行分组
sql 实现:
select
id
,max(days) as days
from
(select
id
,new_flag
,sum(days)+count(*)-max(1) as days
from
(
select
id
,flag
,days
,falg -rank as new_falg
from
(select
id
,flag
,days
,rank() over(partition by id order by flag) as rank
from
(select
id
,flag
,count(dt) as days
from (
select
id
,dt
,dt -rk as flag
from (
select
id
,dt
rank()over(partition by id order by dt) rk
from tablename;
)t1
)t2
group by
id
,flag
)t3
)t4
)t5
group by
id
,new_flag
)t6
group by
id;
备注:这种方法有个弊端,像俄罗斯套娃,当条件发生改变,比如断5天也算连续,你要重复5次;
方法2
思路:采用lag开窗函数
sql 实现:
select
id
,flag
,datediff(max(dt),min(dt))+1
from
(
select
id
,dt
sum(if(dtDiff >2,1,0)) over (partition by id order by dt) as flag
from (
select
id
,dt
,datediff(dt,lagDt) as dtDiff
from (
select
id
,dt
,lag(dt,1,'1970-01-01') over(partition by id order by dt) lagDt
from tablename
)t1
)t2
)t3
group by
id
,flag
备注:断一天也算连续,则 sum(if(dtDiff >2,1,0))处为2
断n天也算连续, 则 sum(if(dtDiff >n+1,1,0))处为n+1
以上是关于Hive计算最大连续登陆天数的主要内容,如果未能解决你的问题,请参考以下文章