hive之分析窗函數

       hive提供很多的分析函數,用於完成統計分析,之前一直沒學習,最近有用到,特意來學習一下。其中感謝很多博客,提供了很多知識和信息。


1.數據準備

          

drop table if exists table tmp.lxw1234;
CREATE EXTERNAL TABLE tmp.lxw1234 (  
cookieid string,  
createtime string,    
pv INT  
) ROW FORMAT DELIMITED   
FIELDS TERMINATED BY ','   
stored as textfile
;


desc lxw1234;

cookieid                string                                      
createtime              string                                      
pv                      int  


把txt文件的數據灌進去

 select * from lxw1234;
OK
cookie1 2015-04-16      4
cookie1 2015-04-15      4
cookie1 2015-04-14      2
cookie1 2015-04-13      3
cookie1 2015-04-12      7
cookie1 2015-04-11      5
cookie1 2015-04-10      1

2.簡單的例子:先看一個大家常用的

select cookieid,sum(pv) from lxw1234 group by cookieid;     (1)

結果:

cookie1    26

計算sum,這裏使用的是group by進行分組。


和上面有類似功能的語句:

select cookieid,sum(pv) over(partition by cookieid) from lxw1234;    (2)


結果:

cookie1 26
cookie1 26
cookie1 26
cookie1 26
cookie1 26
cookie1 26
cookie1 26


這兩個語句用相同之處,也有不同之處

(1)對於group by進行分組的字段進行pv的求和,將所有pv相加返回結果

(2)使用partition by進行分組,分組內的所有字段進行求和,並返回結果。

不同呢?對於此表,cookie1會話,在不同時間的pv是不同的

如果我們這樣寫?

select cookieid,createtime,pv,sum(pv)  from lxw1234 group by cookie,createtime,pv;   (3)

結果:

cookie1 2015-04-10      1       1
cookie1 2015-04-11      5       5
cookie1 2015-04-12      7       7
cookie1 2015-04-13      3       3
cookie1 2015-04-14      2       2
cookie1 2015-04-15      4       4
cookie1 2015-04-16      4       4

分組條件變成了3個,不同cookieid,createtime,pv進行分組求和


select cookieid,createtime,pv,sum(pv) over(partition by cookieid) from lxw1234;           (4)

結果:

cookie1 2015-04-10      1       26
cookie1 2015-04-11      5       26
cookie1 2015-04-12      7       26
cookie1 2015-04-13      3       26
cookie1 2015-04-14      2       26
cookie1 2015-04-15      4       26
cookie1 2015-04-16      4       26

(4)如果想達到(3)的效果,可以這樣寫

select cookieid,createtime,pv,sum(pv) over(partition by cookieid,createtime,pv)
 from lxw1234;

cookie1 2015-04-10      1       1
cookie1 2015-04-11      5       5
cookie1 2015-04-12      7       7
cookie1 2015-04-13      3       3
cookie1 2015-04-14      2       2
cookie1 2015-04-15      4       4
cookie1 2015-04-16      4       4


但是如果(3)想達到(4)的效果,卻沒有辦法


select cookieid,createtime,pv,sum(pv) 
from lxw1234 
group by  cookieid;  

這樣的語句會報錯!


所以,over()這樣的窗口函數更靈活一點。具體我們再來看一下其他的例子。



3.sum

數據:

cookie1 2015-04-10      1  
cookie1 2015-04-11      5  
cookie1 2015-04-12      7  
cookie1 2015-04-13      3  
cookie1 2015-04-14      2  
cookie1 2015-04-15      4  
cookie1 2015-04-16      4 

SELECT 
cookieid,  
createtime,  
pv,  
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime) AS pv1, -- 默認爲從起點到當前行  
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS pv2, --從起點到當前行,結果同pv1   
SUM(pv) OVER(PARTITION BY cookieid) AS pv3, --分組內所有行  
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS pv4,  --當前行+往前3行  
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING) AS pv5,  --當前行+往前3行+往後1行  
SUM(pv) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS pv6  ---當前行+往後所有行    
FROM lxw1234;  

結果:

cookieid createtime     pv      pv1      pv2      pv3      pv4      pv5      pv6
cookie1 2015-04-10       1       1       1       26      1       6       26
cookie1 2015-04-11      5       6       6       26      6       13      25
cookie1 2015-04-12      7       13      13      26      13      16      20
cookie1 2015-04-13      3       16      16      26      16      18      13
cookie1 2015-04-14      2       18      18      26      17      21      10
cookie1 2015-04-15      4       22      22      26      16      20      8
cookie1 2015-04-16      4       26      26      26      13      13      4

partition by:分組     order by :默認爲升序

pv1:分組內所有行,order by的升序,默認從起點行到當前行

        11號的pv1=起點行10號pv+當前行11號的pv=1+5=6

        12號的pv1=起點行10號pv+11號的pv+當前行12號的pv=1+5+7=13

         同理。。。


pv2:ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
      與pv1同理,從起點到當前行


pv3:分組內(cookieid)所有的pv累加

       pv3=1+5+7+3+2+4+4=26

      注意與pv1的不同,差別在於少了order by createtime


pv4:ROWSBETWEEN 3 PRECEDING AND CURRENT ROW

       分組內當前行往前3行+當前行

       14號的pv4=11號的pv+12號的pv+13號的pv+當前行14號的pv=5+7+3+2=17

       15號的pv4=12號的pv+13號的pv+14號的pv+當前行15號的pv=7+3+2+4=16

       同理。。。


pv5:ROWSBETWEEN 3 PRECEDING AND 1 FOLLOWING

        分組內當前行往前3行+當前行+當前行往後1行

      14號的pv5=11號的pv+12號的pv+13號的pv+當前行14號的pv+15號的pv=5+7+3+2+4=21

      15號的pv5=12號的pv+13號的pv+14號的pv+當前行15號的pv+16號的pv=7+3+2+4+4=20

       同理。。。。


pv6:ROWSBETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING

        分組內當前行+往後的所有行

      10號的pv6=10號的pv+11號的pv+12號的pv+13號的pv+14號的pv+15號的pv+16號的pv=26

       11號的pv6=11號的pv+12號的pv+13號的pv+14號的pv+15號的pv+16號的pv=25

      14號的pv6=14號的pv+15號的pv+16號的pv=10

      同理。。。


如果不指定ROWS BETWEEN,默認爲從起點到當前行;
如果不指定ORDER BY,則將分組內所有值累加;
關鍵是理解ROWS BETWEEN含義,也叫做WINDOW子句
PRECEDING:往前
FOLLOWING:往後
CURRENT ROW:當前行
UNBOUNDED:起點,UNBOUNDED PRECEDING 表示從前面的起點, UNBOUNDED FOLLOWING:表示到後面的終點


AVG,MIN,MAX和sum同理。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章