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
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同理。。。