HQL求連續活躍用戶並完成相關統計(基於等差數列原理)

需求

有日誌如下,寫出代碼求得所有用戶和活躍用戶總數及平均年齡。(活躍用戶指連續兩天都有訪問記錄的用戶)
日期 用戶 年齡
dt string,user_id string,age int
2019-02-11,test_1,23
2019-02-11,test_2,19
2019-02-11,test_3,39
2019-02-11,test_1,23
2019-02-11,test_3,39
2019-02-11,test_1,23
2019-02-12,test_2,19
2019-02-13,test_1,23
2019-02-15,test_2,19
2019-02-16,test_2,19
create table user_age(dt string,user_id string,age int)row format delimited fields terminated by ‘,’;

分析:
相信所有用戶的相關指標並不難求,關鍵在於活躍用戶的求取。這裏關於活躍用戶的定義是連續兩天有訪問記錄。可能有的小夥伴會想到用lag或lead函數,這裏的指標是連續兩天確實可以。但如果活躍定義指標業務口徑爲連續7天、30天有訪問記錄呢?

在此換一種思路,基於row_number對dt字段進行自然排序(默認升序,注意在此之前先進行數據去重)獲得dtrk。而後將dt減去dtrk得到日期diff。結果如下:
在這裏插入圖片描述

基於等差數列原理,不難發現連續活躍的日期下會得到相同的diff。而後基於user_id,diff進行聚合即可得到用戶的連續活躍天數
在這裏插入圖片描述
而後取出連續天數seqactive最大值,並進行過濾即得到目標。爲了方便後續操作,在此添加了狀態列state。
在這裏插入圖片描述
最後進行union all兩表(全部用戶、活躍用戶相關指標)
在這裏插入圖片描述
代碼如下:

求獲取全部用戶(連續兩天有訪問記錄)相關指標,採用等等差數列原理
1、去重
select user_id,age,dt from user_age group by user_id,age,dt;  =>t1

2、求所有用戶的平均年齡
select  'all' state  ,sum(1) userCount,avg(age) avgAge from 
t1;  =>tt

求獲取活躍用戶(連續兩天有訪問記錄)相關指標,採用等等差數列原理
1、按照user_id進行分組,按訪問時間進行排序row_number
select user_id,dt, row_number() over(partition by user_id order by dt) dtrk ,age from 
t1;  =>t2

2、計算日期與rk的差值
select user_id,dt,dtrk,date_sub(dt,dtrk) as diff ,age from 
t2; =>t3

3、按差值進行聚合統計,日期差值相同的即爲連續活躍的記錄
select user_id,age ,count(*) seqActive from 
t3 
group by user_id,age,diff; =>t4

4、取出活躍天數最大值,去重
select user_id,age ,max(seqActive)   seqActiveMax from 
t4
group by user_id,age;  =>t5

5、過濾出活躍用戶(最大活躍天數大於2的用戶),並計算活躍用戶總數以及平均年齡,添加狀態列
select  'active' state  , sum(1) actuserCount,avg(age) actavgAge from 
t5
where seqActiveMax >=2;  =>t6

6、合併兩表(最終結果)

select *from 
(select  'all' state  , sum(1) userCount,avg(age) avgAge from 
(select user_id,age from user_age group by user_id,age)t1)tt
union all
select  'active' state  , sum(1) actuserCount,avg(age) actavgAge from 
(select user_id,age ,max(seqActive)   seqActiveMax from 
(select user_id,age ,count(*) seqActive from 
(select user_id,dt,dtrk,date_sub(dt,dtrk) as diff ,age from 
(select user_id,dt, row_number() over(partition by user_id order by dt) dtrk ,age from 
(select user_id,age,dt from user_age group by user_id,age,dt)t1)t2)t3 
group by user_id,age,diff)t4
group by user_id,age)t5
 where seqActiveMax >=2  ;
發佈了132 篇原創文章 · 獲贊 40 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章