1. 程式人生 > >資料統計分析時常用sql語句 (split , row_number , group by, max 等 )

資料統計分析時常用sql語句 (split , row_number , group by, max 等 )

統計分析及建表過程中通常會遇到這樣的需求,比如:

1. 統計以逗號分隔的標籤數,哪個最受歡迎,以及作為內容推薦的資料來源

2. 分組排序url的pv, 取topN的列表

3. 經常會有名字重複的url記錄,取pv最大的那條, 剩下的剔除

下面逐一對以上場景進行總結, 用的是 hivesql,希望有同樣需求的同學可以快速應用,如果有不對的地方還請指正:) 

1. 統計以逗號分隔的標籤數,哪個最受歡迎

hive表中tag列經常是這樣的

--統計以逗號分隔的tags的分佈

--其中tags是你打算展開的原先以逗號分隔的那一列,
--tags_split 是展成多行後的每個tag組成的列, 
--alias是別名,可以自己任意定
--然後group by, 統計個數分佈 
select tags_split,count(*) as n from ( select tags_split from table1 LATERAL VIEW explode(split(tags,",")) alias AS tags_split where date = '20141119' )a group by tags_split order by n desc;

2. 分組排序url的pv, 取topN的列表

--首先統計下pv大於100的url及對應的pv


select url, url_name, host, count(*) as pv 
from table1 a
where
date = '20141119' group by url, url_name, host having count(*) > 100

--如果還想按同一域名下url取pv倒序後的top20,可以這樣寫

select * 
from 
(
select *, 
ROW_NUMBER ( ) OVER (partition by host order by pv desc)  as host_pv_rank  
from
(
select url, url_name, host, count(*) as pv 
from table1 a
where date = '20141119'
group by url, url_name, host having count(*) > 100 )a )a where host_pv_rank <= 20 order by host_pv_rank;

3. 經常會有名字重複的url記錄,要取pv最大的那條, 剩下的剔除

 
方法1:在沒有row_number函式的情況下:

select 
source.*,
case when dup.pv_max is null then 0 else 1 end as no_dup_flag 
--如果找不到即為重複的,只有最大的那個是1

from 
(
select url, url_name, count(*) as pv 
from table1 a
where date = '20141119'
group by url ,url_name
having count(*) > 100
)source 

left outer join 
(
select url_name, max(pv) as pv_max from 
(
select url, url_name, count(*) as pv 
from table1 a
where date = '20141119'
group by url, url_name
having count(*) > 100
)a 
group by url_name
)dup

on source.url_name = dup.url_name
and source.pv = dup.pv_max  

--與最大的那條記錄通過 url_name
--與最大那條的pv進行關聯,只有url_name與pv同時相等才能關聯得上
--否則就是重名的但pv小的記錄,我們這裡將重複的記錄標記出來

方法2:在有row_number函式的情況下:


select 
source.*,
ROW_NUMBER ( ) OVER (partition by url_name order by pv desc)  as dup_flag
-- dup_flag > 1 即為重複的
from 
(
select url, url_name, count(*) as pv 
from table1 a
where date = '20141119'
group by url ,url_name
having count(*) > 100
)source 

 經測試,方法2要快很多(因為沒有了求max 和 join的操作)

sql作為流行的查詢語言,不管是hive, 還是spark, 都對sql有很好的支援,

與此同時,像item based推薦等複雜一些的模型演算法,也可以通過sql的方式很方便地解決,

樓主感覺掌握好sql,對日常的統計分析工作,快速驗證資料準確性,快速展現設計結果,甚至對產品優化改進都很有幫助,

所以大家一起努力學習吧:)