第 1 題 連續問題
如下數據為螞蟻森林中用戶領取的減少碳排放量
id dt lowcarbon 1001 2021-12-12 123 1002 2021-12-12 45 1001 2021-12-13 43 1001 2021-12-13 45 1001 2021-12-13 23 1002 2021-12-14 45 1001 2021-12-14 230 1002 2021-12-15 45 1001 2021-12-15 23 … …
找出連續 3 天及以上減少碳排放量在 100 以上的用戶
第 2 題 分組問題
如下為電商公司用戶訪問時間數據
id ts(秒)
1001 17523641234
1001 17523641256
1002 17523641278
1001 17523641334
1002 17523641434
1001 17523641534
1001 17523641544
1002 17523641634
1001 17523641638
1001 17523641654
某個用戶連續的訪問記錄如果時間間隔小於 60 秒,則分為同一個組,結果為:
id ts(秒) group
1001 17523641234 1
1001 17523641256 1
1001 17523641334 2
1001 17523641534 3
1001 17523641544 3
1001 17523641638 4
1001 17523641654 4
1002 17523641278 1
1002 17523641434 2
1002 17523641634 3
第 3 題 間隔連續問題
某游戲公司記錄的用戶每日登錄數據
id dt
1001 2021-12-12
1002 2021-12-12
1001 2021-12-13
1001 2021-12-14
1001 2021-12-16
1002 2021-12-16
1001 2021-12-19
1002 2021-12-17
1001 2021-12-20
計算每個用戶最大的連續登錄天數,可以間隔一天。解釋:如果一個用戶在 1,3,5,6 登錄游戲,則視為連續 6 天登錄。
第 4 題 打折日期交叉問題
如下為平台商品促銷數據:字段為品牌,打折開始日期,打折結束日期
brand stt edt oppo 2021-06-05 2021-06-09 oppo 2021-06-11 2021-06-21 vivo 2021-06-05 2021-06-15 vivo 2021-06-09 2021-06-21 redmi 2021-06-05 2021-06-21 redmi 2021-06-09 2021-06-15 redmi 2021-06-17 2021-06-26 huawei 2021-06-05 2021-06-26 huawei 2021-06-09 2021-06-15 huawei 2021-06-17 2021-06-21
計算每個品牌總的打折銷售天數,注意其中的交叉日期,比如 vivo 品牌,第一次活動時間為 2021-06-05 到 2021-06-15,第二次活動時間為 2021-06-09 到 2021-06-21 其中 9 號到 15號為重復天數,只統計一次,即 vivo 總打折天數為 2021-06-05 到 2021-06-21 共計 17 天。
第 5 題 同時在線問題
如下為某直播平台主播開播及關播時間,根據該數據計算出平台最高峰同時在線的主播人數。
id stt edt
1001 2021-06-14 12:12:12 2021-06-14 18:12:12
1003 2021-06-14 13:12:12 2021-06-14 16:12:12
1004 2021-06-14 13:15:12 2021-06-14 20:12:12
1002 2021-06-14 15:12:12 2021-06-14 16:12:12
1005 2021-06-14 15:18:12 2021-06-14 20:12:12
1001 2021-06-14 20:12:12 2021-06-14 23:12:12
1006 2021-06-14 21:12:12 2021-06-14 23:15:12
1007 2021-06-14 22:12:12 2021-06-14 23:10:12
答案:自己一定要先做,不要直接看答案!!!
第一題:
1)按照用戶ID以時間字段分組,計算每個用戶單日減少的碳排放量大於100的
select id, dt, sum(lowcarbon) lowcarbon from test1 group by id,dt having lowcarbon > 100;t1
2)等差數列:兩個等差數列若等差相同,則相同位置的數列相減得到的結果相同
按照用戶分組,同時按照時間排序,計算每條數據的Rank值
select id, dt, lowcarbon, rank() over(partition by id order by dt) rk from t1;t2
3)將每行數據中的日期減去Rank值
select id, dt, lowcarbon, date_sub(dt,rk) flag from t2;t3
4)按照用戶以及flag分組,找出記錄大於等於3條的
select id, flag, count(*) num from t3 group by id,flag having num >= 3;
5)最終的HQL
select id, flag, count(*) num from ( select id, dt, lowcarbon, date_sub(dt,rk) flag from ( select id, dt, lowcarbon, rank() over(partition by id order by dt) rk from ( select id, dt, sum(lowcarbon) lowcarbon from test1 group by id,dt having lowcarbon > 100 ) t1 ) t2 ) t3 group by id,flag having num >= 3;
第二題:
1)將上一行時間數據下移
select id, ts, lag(ts,1,0) over(partition by id order by ts) lagts from test2;t1
2)將當前行的時間減去上一行的時間
select id, ts, ts-lagts diffts from t1;t2
3)每個用戶范圍內從第一行到當前行,判斷diffts是否大於等於60,若diffts>=60,則加1,否則不變
select id, ts, sum(if(diffts>=60,1,0)) over(partition by id order by ts) groupid from t2;t3
4)最終的HQL
select id, ts, sum(if(diffts>=60,1,0)) over(partition by id order by ts) groupid from ( select id, ts, ts-lagts diffts from ( select id, ts, lag(ts,1,0) over(partition by id order by ts) lagts from test2 ) t1 ) t2
第三題:
1)將上一行時間下移
select id, dt, lag(dt,1,'1970-01-01') lagdt from test3;t1
2)將當前行時間減去上一行時間
select id, dt, datediff(dt,lagdt) diffdt from t1;t2
3)按照用戶分組,並按時間排序,計算第一行到當前行大於2的數據總條數
select id, dt, sum(if(diffdt>2,1,0)) groupid from t2;t3
4)按照用戶和groupid分組,求最大時間減去最小時間,然后加1
select id, groupid, (max(dt)-min(dt)+1) maxday from t3;t4
5)取連續登錄天數的最大值
select id, max(maxday) loginmax from t4 group by id
6)最終的HQL
select id, max(maxday) loginmax from ( select id, groupid, (max(dt)-min(dt)+1) maxday from ( select id, dt, sum(if(diffdt>2,1,0)) groupid from ( select id, dt, datediff(dt,lagdt) diffdt from ( select id, dt, lag(dt,1,'1970-01-01') lagdt from test3 ) t1 ) t2 ) t3 ) t4 group by id
第四題:
1)將當前行以前的數據中最大的edt放置當前行
select id, stt, edt, max(edt) over(partition by id order by stt rows unbounded preceding and 1 preceding) maxEdt from test4;t1
2)比較開始時間與移動下來的時間,若開始時間大,則不需要操作,否則,需要將移動下來的時間加1替換當前行的開始時間,若第一行數據,maxEdt為null,不需要操作
select id, if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt, edt from t1;t2
3)將每行數據中的結束日期減去開始日期
select id, datediff(edt,stt) day from t2;t3
4)按照品牌分組,計算每條數據加1的總和
select id, sum(if(day>=0,day+1,0)) days from t3 group by id;
5)最終的HQL
select id, sum(if(day>=0,day+1,0)) days from ( select id, datediff(edt,stt) day from ( select id, if(maxEdt is null,stt,if(stt>maxEdt,stt,date_add(maxEdt,1))) stt, edt from ( select id, stt, edt, max(edt) over(partition by id order by stt rows unbounded preceding and 1 preceding) maxEdt from test4 ) t1 ) t2 ) t3 group by id;
第五題:
1)對數據分類,在開始時間后添加1,表示有主播上線,同時在關閉時間后添加-1,表示有主播下線
select id, stt dt, 1 p from test5 union select id, edt dt, -1 p from test5;t1
2)按照時間排序,計算累加人數
select id, dt, sum(p) over(order by dt) sum_p from t1;t2
3)找出同時在線人數最大值
select max(sum_p) from t2;
4)最終的HQL
select max(sum_p) from ( select id, dt, sum(p) over(order by dt) sum_p from ( select id, stt dt, 1 p from test5 union select id, edt dt, -1 p from test5 ) t1 ) t2;