前幾天遇到一個這樣的需求:銷售總占比加起來超過75%的top分類。具體需求是這樣的:商品一級分類標簽下面有許多商品標簽,例如運動戶外一級標簽,下面可能存在361°,CBA,Nike,Adidas...等這些商品標簽。我們需要統計在一級標簽下面占總銷售比超過75%的商品標簽有哪些,從而讓我們了解一級品牌標簽下面哪些商品比較收用戶喜歡。有以下樣例數據(amount_precnt為這類商品在一級標簽當中銷售占比)。
按照我們的業務需求我們要得到男裝->(優衣庫,七匹狼) 箱包->(coach) 運動戶外->(361°,Nike,CBA)這樣的結果就是符合我們的要求。amount_precnt占比在75%的top分類數據。
拿到這樣的需求以后,思路如下。按照cat_name分組求和。然后在利用lag函數取前一條求和值作為另外一個字段。最后過濾條件為求和值小於0.5或者當前求和值大於0.5並且前一個求和值小於0.5的數據。得到思路以后主要是卡在了怎么按照cat_name依次求和。就是如何將第一條數據的amount_precnt + 第二條數據的amount_precnt。然后前面兩條數據的和在加第三條數據的amount_precnt值。依次這樣類推….后面翻看hive 窗口函數的官網得到資料。在sum() over 里面加上 rows between unbounded preceding and current 可以求當前行和前面n條數據的和。我們先看一下sum() over()得到的效果。amount_percent_num的值都是1.就是求和的值。
select amount_percent, cat_name,brand_num, sum(amount_percent) over(partition by cat_name ) as amount_percent_num from (SELECT * FROM hive_temp_bad.dlyang_1234 order by cat_name) t
然后我們加上rows between unbounded preceding and current
select amount_percent, cat_name,brand_num, sum(amount_percent) over(partition by cat_name ) as amount_percent_num from (SELECT * FROM hive_temp_bad.dlyang_1234 order by cat_name) t
得到了我們想要的結果了。最后我們貼上完整的sql代碼實現上面功能。
1 select cat_name,brand_num,amount_percent from 2 (select *,lag(amount_percent_num,1,0) over(partition by cat_name order by amount_percent_num) as lag1 from 3 (select amount_percent, cat_name,brand_num, 4 sum(amount_percent) over(partition by cat_name order by amount_percent desc rows between unbounded preceding and current row) as amount_percent_num 5 from 6 (SELECT * FROM hive_temp_bad.dlyang_1234 order by cat_name) t ) t2 ) t3 where lag1 < 0.75 or (amount_percent_num > 0.75 and lag1 < 0.75) ORDER BY 7 cat_name,amount_percent desc;
不得不說sql天花板可能真的是窗口函數了。看來以后得要多多學習了。





