數據倉庫項目筆記6

用戶活躍留存:

求出當日以前的所有日期在(當日-每個日期)天后留存
可以用當日的日活join所有的日期日活獲取用戶活躍留存
這樣join表數巨多, 另闢蹊徑 如果有一張表記錄了每個用戶的活躍狀態的日期區間 就能解決以前歷史表不能獲取所有日期用戶是否活躍的問題

用戶活躍記錄拉鍊表 狀態的固定區間然後形成鏈(數據狀態更新不頻繁)

記錄了每個用戶的活躍狀態的日期區間
拉鍊表設計: 需要uid , 用戶首登日期, 用戶連續活躍起始日, 用戶連續活躍結束日
爲了表示活躍是否中斷 如果今日活躍則起始日到結束日(‘9999-12-31’)爲開區間
如果今日不活躍則起始日到結束日(‘2019-09-04’)爲閉區間
爲求出拉鍊表就需要知道今日是否活躍(日活表) 然後join 前拉鍊表
結束日條件:
無區間 有日活 則開區間’9999-12-31’
開區間 無日活 則封閉 今日-1
開區間 有日活 和閉區間 無日活 均保留原始結束日
另一種特殊條件需要增加列
閉區間 有日活 : 過濾掉有開區間的uid , 然後join 日活表 有日活的數據
with dau as(
select dt,uid from demo_dau_dtl where dt=‘2019-06-09’
),
tmp as (
select
uid,first_login
from dws_user_continue_act
group by uid,first_login
having max(continue_end) != ‘9999-12-31’
)

–insert overwrite table dws_user_continue_act

select
if(a.uid is not null,a.uid,b.uid) as uid,
if(a.uid is not null,a.first_login,b.dt) as first_login,
if(a.uid is not null,a.continue_start,b.dt) as continue_start,
case
when a.uid is null then ‘9999-12-31’
when a.continue_end=‘9999-12-31’ and b.uid is null then date_sub(‘2019-06-09’,1)
else a.continue_end
end as continue_end
from
dws_user_continue_act a
full join
dau b
on a.uid=b.uid

union all

select
tmp.uid,
tmp.first_login,
dau.dt as continue_start,
‘9999-12-31’ as continue_end

from tmp join dau on tmp.uid=dau.uid
;

用戶活躍留存解決方案:

±-------±---------------±------------------±----------------+
| t.uid | t.first_login | t.continue_start | t.continue_end |
±-------±---------------±------------------±----------------+
| a | 2019-05-20 | 2019-05-20 | 2019-05-26 |
| a | 2019-05-20 | 2019-05-29 | 2019-06-01 |
| a | 2019-05-20 | 2019-06-03 | 9999-12-31 |
| b | 2019-05-22 | 2019-05-22 | 2019-05-30 |
| b | 2019-05-22 | 2019-06-03 | 2019-06-05 |
| c | 2019-06-03 | 2019-06-03 | 9999-12-31 |
| x | 2019-06-03 | 2019-06-03 | 2019-06-04 |
±-------±---------------±------------------±----------------+
求出今日30日前所有日期 最後一列留存 即29日 1日留存 28日2日留存 等等
每一行需要分裂成多行來得出結果所以用map實現

with tmp as (
select
explode(
map(
date_sub(‘2019-06-09’,1),count(if(continue_start<=date_sub(‘2019-06-09’,1) and continue_end=‘9999-12-31’,1,null)),
date_sub(‘2019-06-09’,2),count(if(continue_start<=date_sub(‘2019-06-09’,2) and continue_end=‘9999-12-31’,1,null)),
date_sub(‘2019-06-09’,3),count(if(continue_start<=date_sub(‘2019-06-09’,3) and continue_end=‘9999-12-31’,1,null)),
date_sub(‘2019-06-09’,4),count(if(continue_start<=date_sub(‘2019-06-09’,4) and continue_end=‘9999-12-31’,1,null)),
date_sub(‘2019-06-09’,5),count(if(continue_start<=date_sub(‘2019-06-09’,5) and continue_end=‘9999-12-31’,1,null)),
date_sub(‘2019-06-09’,6),count(if(continue_start<=date_sub(‘2019-06-09’,6) and continue_end=‘9999-12-31’,1,null)),
date_sub(‘2019-06-09’,7),count(if(continue_start<=date_sub(‘2019-06-09’,7) and continue_end=‘9999-12-31’,1,null))
)
) as(dt,cnts)
from dws_user_continue_act

)

select
key as dt,
datediff(‘2019-06-09’,key) as remain_days,
value as remain_cnts
from tmp
;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章