hive中統計用戶連續交易的總額、連續登陸天數、連續登陸開始和結束時間、間隔天數


在電商、物流和銀行可能經常會遇到這樣的需求:統計用戶連續交易的總額、連續登陸天數、連續登陸開始和結束時間、間隔天數等,那今天就來聊聊這些需求在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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM