hivesql怎么实现循环_⽤HiveSQL计算连续天数问题的⽅法点击右侧关注,⼤数据开发领域最强!
点击右侧关注,暴⾛⼤数据!
在⽇常⼯作中,可能经常会接到业务⽅类似这样的需求:
统计今年每个⽤户最长连续签到的天数;
统计最近⼀个⽉连续有回帖超过5天的话题;
统计本季度中连续3天以上单⽇销量超过100的商品。
这种“连续天数”问题看似简单,但实际上对思维能⼒和编写复杂SQL语句的能⼒要求⽐较⾼。下⾯以我们曾经接到的⼀个需求为例,提出解决办法。
create table user_calendar_record (user_id bigint comment '⽤户ID',event_type int comment '记录类型',event_data string comment '记录数据',upload_time string comment '上传时间'del_status int comment '删除状态') partitioned by (pt_date string comment '记录(分区)⽇期');
现要出4⽉间,每个⽤户类型为24的记录项。如果有⽤户连续⼀周及以上记录该项,说明TA对某⽅⾯特别重视,应当重点运营。
编写SQL的思路如下。为了避免过多嵌套,所有步骤中都先⽤⼦表表⽰,最后再合成完成的语句。
1. 以⽤户ID分组,以记录⽇期为排序规则,添加⼀列排名。由于⽤户每天可以记录不⽌⼀次,所以要采⽤dense_rank()函数,不能⽤
rank()或row_number()。
(select user_id,pt_date,dense_rank() over(partition by user_id order by pt_date) as date_rankfrom
user_calendar_recordwhere pt_date >= 20190401 and pt_date <= 20190430and event_type = 24 and del_status = 0) t_a;
2. 在以上添加了排名的表中,⽤记录⽇期减去排名列代表的天数,得到另⼀个⽇期。该⽇期实际上就是⼀个连续⽇期序列的第⼀天⽇期减去⼀天(读起来有点拗⼝,但很容易理解),⽤它来做标记。
(select user_id,pt_date,date_sub(pt_date, cast(date_rank as int)) as start_pointfrom t_a) t_b;
3.以上表中的user_id和start_point为分组依据,计算每个连续⽇期序列的天数值。因为数据量不⼤,所以这⾥直接⽤了distinct。数据量⼤的话还是应该采⽤group by来代替distinct。
4. 最后就可以筛选出天数值最⼤值>=7的那些记录了。
select user_id,max(day_count) as max_day_countfrom t_cgroup by uidhaving max(day_count) >= 7;
将上⾯的4个步骤合起来,就是如下的完整SQL语句了:
select user_id,max(day_count) as max_day_countfrom (select user_id,start_point,count(distinct pt_date) as day_countfrom (select user_id,pt_date,date_sub(pt_date, cast(date_rank as int)) as start_pointfrom (select user_id,pt_date,dense_rank()
over(partition by user_id order by pt_date) as date_rankfrom user_calendar_recordwhere pt_date >= 20190401 and pt_date <= 20190430and event_type = 24 and del_status = 0) t_a) t_bgroup by user_id,start_point) t_cgroup by
user_idhaving max(day_count) >= 7;
如果还需要同时得到最⼤连续天数对应的起始⽇期怎么办呢?
可以将⽇期计数值存成⼀张临时表,连续⽇期最⼤值存成另⼀张临时表,
然后两表做join就可以得到结果了。rank函数怎么用
欢迎点赞+收藏+转发朋友圈素质三连
⽂章不错?点个【在看】吧!