在電商、物流和銀行可能經常會遇到這樣的需求:統計用戶連續交易的總額、連續登陸天數、連續登陸開始和結束時間、間隔天數等,那今天就來聊聊這些需求在hive中的實現方法
先創建測試表
create table deal_tb (id int, daystr varchar(10), amount decimal(10,2));
1再插入模擬數據
insert into deal_tb values (1, "2019-02-08", 6214.23), (1, "2019-02-08", 6247.32), (1, "2019-02-09", 85.63), (1, "2019-02-09", 967.36), (1, "2019-02-10", 85.69), (1, "2019-02-12", 769.85), (1, "2019-02-13", 943.86), (1, "2019-02-14", 538.42), (1, "2019-02-15", 369.76), (1, "2019-02-16", 369.76), (1, "2019-02-18", 795.15), (1, "2019-02-19", 715.65), (1, "2019-02-21", 537.71), (2, "2019-02-08", 6214.23), (2, "2019-02-08", 6247.32), (2, "2019-02-09", 85.63), (2, "2019-02-09", 967.36), (2, "2019-02-10", 85.69), (2, "2019-02-12", 769.85), (2, "2019-02-13", 943.86), (2, "2019-02-14", 943.18), (2, "2019-02-15", 369.76), (2, "2019-02-18", 795.15), (2, "2019-02-19", 715.65), (2, "2019-02-21", 537.71), (3, "2019-02-08", 6214.23), (3, "2019-02-08", 6247.32), (3, "2019-02-09", 85.63), (3, "2019-02-09", 967.36), (3, "2019-02-10", 85.69), (3, "2019-02-12", 769.85), (3, "2019-02-13", 943.86), (3, "2019-02-14", 276.81), (3, "2019-02-15", 369.76), (3, "2019-02-16", 369.76), (3, "2019-02-18", 795.15), (3, "2019-02-19", 715.65), (3, "2019-02-21", 537.71);
注意:每個用戶每天可能會有多條記錄
所以我們先按用戶和日期分組求和,使每個用戶每天只有一條數據
select id, daystr, sum(amount) amount from deal_tb group by id, daystr; OK id daystr amount 1 2019-02-08 12461.55 1 2019-02-09 1052.99 1 2019-02-10 85.69 1 2019-02-12 769.85 1 2019-02-13 943.86 1 2019-02-14 538.42 1 2019-02-15 369.76 1 2019-02-16 369.76 1 2019-02-18 795.15 1 2019-02-19 715.65 1 2019-02-21 537.71 2 2019-02-08 12461.55 2 2019-02-09 1052.99 2 2019-02-10 85.69 2 2019-02-12 769.85 2 2019-02-13 943.86 2 2019-02-14 943.18 2 2019-02-15 369.76 2 2019-02-18 795.15 2 2019-02-19 715.65 2 2019-02-21 537.71 3 2019-02-08 12461.55 3 2019-02-09 1052.99 3 2019-02-10 85.69 3 2019-02-12 769.85 3 2019-02-13 943.86 3 2019-02-14 276.81 3 2019-02-15 369.76 3 2019-02-16 369.76 3 2019-02-18 795.15 3 2019-02-19 715.65 3 2019-02-21 537.71 Time taken: 43.875 seconds, Fetched: 32 row(s)
根據用戶ID分組按日期排序,將日期和分組序號相減得到連續登陸的開始日期(from_day),如果開始日期相同說明連續登陸
-- 根據用戶ID分組按日期排序,將日期和分組序號相減得到連續登陸的開始日期,如果開始日期相同說明連續登陸 select id, daystr, amount, date_sub(daystr, row_number() over(partition by id order by daystr)) from_day -- 日期減去分區排序的序號,如果新日期相等,則連續登陸 from ( -- 按用戶和日期分區求和,使每個用戶每天只有一條數據 select id, daystr, sum(amount) amount from deal_tb group by id, daystr ); OK id daystr amount from_day 1 2019-02-08 12461.55 2019-02-07 1 2019-02-09 1052.99 2019-02-07 1 2019-02-10 85.69 2019-02-07 1 2019-02-12 769.85 2019-02-08 1 2019-02-13 943.86 2019-02-08 1 2019-02-14 538.42 2019-02-08 1 2019-02-15 369.76 2019-02-08 1 2019-02-16 369.76 2019-02-08 1 2019-02-18 795.15 2019-02-09 1 2019-02-19 715.65 2019-02-09 1 2019-02-21 537.71 2019-02-10 2 2019-02-08 12461.55 2019-02-07 2 2019-02-09 1052.99 2019-02-07 2 2019-02-10 85.69 2019-02-07 2 2019-02-12 769.85 2019-02-08 2 2019-02-13 943.86 2019-02-08 2 2019-02-14 943.18 2019-02-08 2 2019-02-15 369.76 2019-02-08 2 2019-02-18 795.15 2019-02-10 2 2019-02-19 715.65 2019-02-10 2 2019-02-21 537.71 2019-02-11 3 2019-02-08 12461.55 2019-02-07 3 2019-02-09 1052.99 2019-02-07 3 2019-02-10 85.69 2019-02-07 3 2019-02-12 769.85 2019-02-08 3 2019-02-13 943.86 2019-02-08 3 2019-02-14 276.81 2019-02-08 3 2019-02-15 369.76 2019-02-08 3 2019-02-16 369.76 2019-02-08 3 2019-02-18 795.15 2019-02-09 3 2019-02-19 715.65 2019-02-09 3 2019-02-21 537.71 2019-02-10 Time taken: 85.875 seconds, Fetched: 32 row(s)
統計用戶連續交易的總額、連續登陸天數、連續登陸開始和結束時間、間隔天數
select id, case when count(1) >= 3 then sum(amount) else -100 end sum_amount, -- 連續大於三天的交易總額,不滿足的賦值為-100 min(daystr) start_date, -- 連續登陸的開始時間 max(daystr) end_date, -- 連續登陸的結束時間 count(1) continuous_day, -- 連續登陸的天數 datediff(from_day, lag(from_day, 1, from_day) over(partition by id order by from_day)) interval_day-- 間隔多少天沒交易 from ( -- 根據用戶ID分組按日期排序,將日期和分組序號相減得到連續登陸的開始日期,如果開始日期相同說明連續登陸 select id, daystr, amount, date_sub(daystr, row_number() over(partition by id order by daystr)) from_day -- 日期減去分區排序的序號,如果新日期相等,則連續登陸 from ( -- 按用戶和日期分區求和,使每個用戶每天只有一條數據 select id, daystr, sum(amount) amount from deal_tb group by id, daystr ) a ) b group by id, from_day; OK id sum_amount start_date end_date continuous_day interval_day 1 13600.23 2019-02-08 2019-02-10 3 0 1 2991.65 2019-02-12 2019-02-16 5 1 1 -100.00 2019-02-18 2019-02-19 2 1 1 -100.00 2019-02-21 2019-02-21 1 1 2 13600.23 2019-02-08 2019-02-10 3 0 2 3026.65 2019-02-12 2019-02-15 4 1 2 -100.00 2019-02-18 2019-02-19 2 2 2 -100.00 2019-02-21 2019-02-21 1 1 3 13600.23 2019-02-08 2019-02-10 3 0 3 2730.04 2019-02-12 2019-02-16 5 1 3 -100.00 2019-02-18 2019-02-19 2 1 3 -100.00 2019-02-21 2019-02-21 1 1 Time taken: 87.16 seconds, Fetched: 12 row(s)
---------------------
作者:浮雲6363
來源:CSDN
原文:https://blog.csdn.net/lz6363/article/details/87209532
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!