【开窗】求连续天数

本文介绍如何利用大数据技术,通过Hadoop和Hive解决计算学生连续学习天数的问题。首先,提供了学生课程表的数据结构和样本数据。接着,通过排序和完成时间对比的方法,详细阐述了数据处理的思路。最后,给出了具体的Hive SQL查询实现,以计算每个学生的最大连续学习天数。

问题描述:

一张表:student_schedule(学生课程表)

字段comment:学生ID,课程ID,完成时间

问题:学生在一天内完成一节课,当前天记录为完成学习,现计算连续学习天数

————————————————————————————————————————————————————————————————————————

思路:

连续学习,使用排序和完成时间做对比

————————————————————————————————————————————————————————————————————————

数据准备:

1、
create table if not exists student_schedule(
student_id bigint 
,lesson_id bigint 
,finish_date STRING   
);
2、
insert OVERWRITE table student_schedule 
select 1,100,'2019-08-01 00:00:00'
union all 
select 1,200,'2019-08-01 00:00:00'
union all 
select 1,100,'2019-08-02 00:00:00'
union all 
select 1,200,'2019-08-02 00:00:00'
union all 
select 1,100,'2019-08-03 00:00:00'
union all 
select 1,200,'2019-08-03 00:00:00'
union all 
select 1,100,'2019-08-04 00:00:00'
union all 
select 1,100,'2019-08-06 00:00

Hive SQL中计算最大连续活跃天数,可按以下思路和步骤进行: ### 思路分析 要计算最大连续活跃天数,关键在于将连续活跃的日期分组,然后统计每组的天数,最后找出最大的连续天数。可使用开窗函数`row_number`结合日期运算来实现分组。 ### 示例代码 以引用[3]的数据为例,先创建测试表并插入数据: ```sql -- 创建测试表 create table tmpdb.test_01 as select '1001' as user_id, '2017-01-01' as login_date union all select '1001' as user_id, '2017-01-02' as login_date union all select '1001' as user_id, '2017-01-04' as login_date union all select '1001' as user_id, '2017-01-06' as login_date union all select '1001' as user_id, '2017-01-07' as login_date; ``` 接着编写SQL计算最大连续活跃天数: ```sql -- 计算最大连续活跃天数 SELECT user_id, MAX(consecutive_days) as max_consecutive_days FROM ( SELECT user_id, grp, COUNT(*) as consecutive_days FROM ( SELECT user_id, login_date, -- 将日期减去对应的排名,连续日期相减后结果相同,用于分组 date_sub(login_date, row_number() over (partition by user_id order by login_date)) as grp FROM tmpdb.test_01 ) t1 GROUP BY user_id, grp ) t2 GROUP BY user_id; ``` ### 代码解释 1. **内层子查询**:使用`row_number`函数对每个用户的登录日期进行排名,再用`date_sub`函数将登录日期减去排名,得到一个新的字段`grp`。连续活跃的日期相减后`grp`值相同,这样就把连续活跃的日期分到了同一组。 2. **中间子查询**:按用户和`grp`分组,统计每组的记录数,即连续活跃的天数。 3. **外层查询**:按用户分组,找出每个用户的最大连续活跃天数。 ### 另一种示例 以引用[5]的数据为例,也可按上述思路计算最大连续活跃天数: ```sql -- 先创建表并插入数据 CREATE TABLE user_activity ( user_id INT, activity_date STRING ); INSERT INTO user_activity VALUES (1, '2022-07-11'), (1, '2022-07-12'), (1, '2022-07-13'), (1, '2022-07-14'), (1, '2022-07-15'), (1, '2022-07-16'), (1, '2022-07-17'), (1, '2022-07-18'), (2, '2022-07-12'), (2, '2022-07-13'), (2, '2022-07-14'), (2, '2022-07-15'), (2, '2022-07-16'), (2, '2022-07-21'), (2, '2022-07-22'), (3, '2022-08-01'), (3, '2022-08-02'), (3, '2022-08-03'), (3, '2022-08-04'), (3, '2022-08-05'), (3, '2022-08-06'), (3, '2022-08-07'), (3, '2022-08-08'), (3, '2022-08-09'), (3, '2022-08-10'), (3, '2022-08-11'); -- 计算最大连续活跃天数 SELECT user_id, MAX(consecutive_days) as max_consecutive_days FROM ( SELECT user_id, grp, COUNT(*) as consecutive_days FROM ( SELECT user_id, activity_date, date_sub(activity_date, row_number() over (partition by user_id order by activity_date)) as grp FROM user_activity ) t1 GROUP BY user_id, grp ) t2 GROUP BY user_id; ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值