問題表述
最近業(yè)務(wù)線故障抑堡,一些用戶受到了影響钓猬。產(chǎn)品經(jīng)理急切需要知道,這次事故是否導(dǎo)致用戶流失乘碑,換句話希望看看這些用戶近一個星期的購物留存检碗。所以產(chǎn)品經(jīng)理給數(shù)據(jù)工程師提供了一個大概有1.4萬的受影響用戶id的文本文件accidentIds.txt,希望通過購買記錄表(order_table)知道從事故發(fā)生當天開始码邻,7天內(nèi)這部分人群的再次消費人數(shù)和消費金額折剃。數(shù)據(jù)按天給出。
- accidentIds.txt數(shù)據(jù)形式像屋。
123
234
345
- order_table表結(jié)構(gòu)
create_time | user_id | purchase |
---|---|---|
2017-07-10 10:20:29 | 123 | 90 |
2017-07-10 23:23:23 | 123 | 30 |
2017-07-11 13:23:23 | 345 | 60 |
2017-07-12 03:23:23 | 234 | 130 |
分析
用戶購買記錄屬于業(yè)務(wù)表怕犁,通常會從mysql抽到hive當中來進行統(tǒng)計計算。而需求方提供的卻是一個文本文件,完成這個需求奏甫,其實最笨的一個做法都是在hive里建一個臨時表戈轿,然后把文件load進去,連表查詢就行了阵子。但是這樣做思杯,真的很麻煩,出數(shù)據(jù)的效率也不高挠进。
這時我們應(yīng)該想起Linux的一個高效工具——awk色乾。
如果我們是從hive中把按天、用戶id领突、夠買金額總和的形式把數(shù)據(jù)導(dǎo)出到服務(wù)器暖璧,然后再awk計算,就會方便會多君旦,出數(shù)據(jù)簡直是秒級別澎办。
具體步驟
假設(shè)當前工作目錄,既是最后輸出目錄金砍。且已經(jīng)把accidentIds.txt拷貝到當前目錄局蚀。接下來:
- 把數(shù)據(jù)導(dǎo)出到buylist.txt
hive -e "
use database_a;
select substr(create_time,1,10) as dt,user_id,sum(purchase)
from order_table
group by substr(create_time,1,10),user_id
">buylist.txt
- awk處理
awk 'NR==FNR{
//把accidentIds.txt的id存到uidDict數(shù)組中,且下標用id標識
uidDict[$1]=$1; }
NR>FNR{
//對于buylist.txt中的記錄捞魁,$2表示user_id只要在uidDict中出現(xiàn)至会,表示有夠買
if(uidDict[$2]!=""){
//$1是夠買日期
day[$1]=$1;
//userCount是按日期計數(shù)數(shù)組,表示夠買過的人數(shù)
userCount[$1]++;
//$3表示某個人某天的夠買金額總和,purchase是按日期累加夠買金額
purchase[$1]=purchase[$1]+$3;}}
END{
//按天輸出
for (i in day) {
print day[i],userCount[i],purchase[i]
}}' accidentIds.txt buylist.txt
輸出
2017-07-10 123 120
2017-07-11 345 60
2017-07-12 234 130
結(jié)語
對于1.4萬條數(shù)據(jù)的accidentIds.txt和38萬條數(shù)據(jù)的buylist.txt谱俭,awk命令的計算結(jié)果簡直是秒出奉件。
而用hive連表,首先導(dǎo)表昆著,再連表查詢县貌,怎么著也得折騰個半個小時。
所以用好awk真心省時省力按斩C汉邸!接谨!