Hive-Sql分析函數彙總

目錄

  0 引 言

  1. 聚合分析函數

  2.排名分析函數

  3.數學分析函數

  4.行偏移量分析函數

  5.多維分析函數


 0 引 言

   分析函數在sql中非常重要,對於sqlboy來說是必須要掌握的 ,本文對Hive-Sql分析函數進行彙總和總結,Hive-Sql分析函數主要有以下五類:

  • 聚合分析函數
  • 排名分析函數
  • 數學分析函數
  • 行偏移量分析函數
  • 多維分析函數

其思維導圖如下所示:

 1. 聚合分析函數

  •         sum 求和
  •        count 統計記錄數
  •        min 求最小值
  •        max 求最大值
  •        avg 求均值

具體案例參考鏈接: https://blog.csdn.net/godlovedaniel/article/details/104977785#6%20%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0

  2.排名分析函數

  •        ROW_NUMBER  正常排序(行號)[1,2,3,4] -- 必須有order_by。適合於生成主鍵,連續序列或者不併列排名
  •        RANK  跳躍排序[1,2,2,4] -- 必須有order_by
  •       DENSE_RANK 密集排序/等位排序[1,2,2,3] -- 必須有order_by
  •       FIRST 從DENSE_RANK返回的集合中取出排在最前面的一個值的行
  •       LAST 從DENSE_RANK返回的集合中取出排在最後面的一個值的行
  •       FIRST_VALUE 返回窗口中第一行某字段值,取分組內排序後,截止到當前行,第一行某字段值
  •      LAST_VALUE 返回窗口中的最後一行某字段值,取分組內排序後,截止到當前行,最後一行某字段值

具體案例參考鏈接: https://blog.csdn.net/godlovedaniel/article/details/104977785#6%20%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0

  3.數學分析函數 

  •       NTILE 用於將分組數據按照順序切分成n片(n桶),返回當前切片值(桶序號).切片值就是桶的序號。類似於hive中分桶,用於求百分比
對於一組數字(1,2,3,4,5,6),ntile(2)切片後爲(1,1,1,2,2,2)

(1,2,3,4,5,6,7),ntile(2)切片後爲(1,1,1,1,2,2,2)

其序號的標定類似於hive中分桶的原理。
又叫分桶函數或分片函數。ntile(n),n表示分桶或分片的個數。
  •      COVAR_POP 返回一對錶達式的總體協方差
  •      COVAR_SAMP 返回一對錶達式的樣本協方差
  •      CUME_DIST 計算一行在組中的相對位置。小於等於當前值的行數/分組內總行數
  •      PERCENT_RANK 分組內當前行的RANK值-1/分組內總行數-1
  •      PERCENTILE_DISC  返回一個與輸入的分佈百分比值相對應的數據值

    舉例如下:

數據準備:

d1,user1,1000
d1,user2,2000
d1,user3,3000
d2,user4,4000
d2,user5,5000
 
CREATE EXTERNAL TABLE lxw1234 (
dept STRING,
userid string,
sal INT
) ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
stored as textfile location '/tmp/lxw11/';
 
 
hive> select * from lxw1234;
OK
d1      user1   1000
d1      user2   2000
d1      user3   3000
d2      user4   4000
d2      user5   5000
CUME_DIST
–CUME_DIST 小於等於當前值的行數/分組內總行數
 –比如,統計小於等於當前薪水的人數,所佔總人數的比例
SELECT 
dept,
userid,
sal,
CUME_DIST() OVER(ORDER BY sal) AS rn1,
CUME_DIST() OVER(PARTITION BY dept ORDER BY sal) AS rn2 
FROM lxw1234;
 
dept    userid   sal   rn1       rn2 
-------------------------------------------
d1      user1   1000    0.2     0.3333333333333333
d1      user2   2000    0.4     0.6666666666666666
d1      user3   3000    0.6     1.0
d2      user4   4000    0.8     0.5
d2      user5   5000    1.0     1.0
 
rn1: 沒有partition,所有數據均爲1組,總行數爲5,
     第一行:小於等於1000的行數爲1,因此,1/5=0.2
     第三行:小於等於3000的行數爲3,因此,3/5=0.6
rn2: 按照部門分組,dpet=d1的行數爲3,
     第二行:小於等於2000的行數爲2,因此,2/3=0.6666666666666666

SELECT 
dept,
userid,
sal,
PERCENT_RANK() OVER(ORDER BY sal) AS rn1,   --分組內
RANK() OVER(ORDER BY sal) AS rn11,          --分組內RANK值
SUM(1) OVER(PARTITION BY NULL) AS rn12,     --分組內總行數
PERCENT_RANK() OVER(PARTITION BY dept ORDER BY sal) AS rn2 
FROM lxw1234;
 
dept    userid   sal    rn1    rn11     rn12    rn2
---------------------------------------------------
d1      user1   1000    0.0     1       5       0.0
d1      user2   2000    0.25    2       5       0.5
d1      user3   3000    0.5     3       5       1.0
d2      user4   4000    0.75    4       5       0.0
d2      user5   5000    1.0     5       5       1.0
 
rn1: rn1 = (rn11-1) / (rn12-1) 
	   第一行,(1-1)/(5-1)=0/4=0
	   第二行,(2-1)/(5-1)=1/4=0.25
	   第四行,(4-1)/(5-1)=3/4=0.75
rn2: 按照dept分組,
     dept=d1的總行數爲3
     第一行,(1-1)/(3-1)=0
     第三行,(3-1)/(3-1)=1

4.不同行字段值比較分析函數(行偏移量分析函數)

  • LAG 可以訪問結果集中的其它行而不用進行自連接。可以訪問當前行之前的行,前偏移量函數,如果沒有指定,偏移量默認爲1
  • LEAD LEAD與LAG相反,LEAD可以訪問當前行之後的行,後偏移量函數,用法同LAG函數

    *注:以上兩個函數功能非常強大,使用較廣 ,可以跨行取任意一個字段的值進行分析比較,採用上述函數避免了自連接操作,提高了效率。面試中也經常會被考察到,如求連續三天登錄的用戶等問題。

5.多維分析函數

  • GROUPING SETS 在一個GROUP BY查詢中,根據不同的維度組合進行聚合,等價於將不同維度的GROUP BY結果集進行UNION ALL
  • GROUPING__ID 表示結果屬於哪一個分組集合
  • CUBE 根據GROUP BY的維度的所有組合進行聚合
  • ROLLUP 是CUBE的子集,以最左側的維度爲主,從該維度進行層級聚合。
數據準備:

2015-03,2015-03-10,cookie1
2015-03,2015-03-10,cookie5
2015-03,2015-03-12,cookie7
2015-04,2015-04-12,cookie3
2015-04,2015-04-13,cookie2
2015-04,2015-04-13,cookie4
2015-04,2015-04-16,cookie4
2015-03,2015-03-10,cookie2
2015-03,2015-03-10,cookie3
2015-04,2015-04-12,cookie5
2015-04,2015-04-13,cookie6
2015-04,2015-04-15,cookie3
2015-04,2015-04-15,cookie2
2015-04,2015-04-16,cookie1
 
CREATE EXTERNAL TABLE lxw1234 (
month STRING,
day STRING, 
cookieid STRING 
) ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
stored as textfile location '/tmp/lxw11/';
 
 
hive> select * from lxw1234;
OK
2015-03 2015-03-10      cookie1
2015-03 2015-03-10      cookie5
2015-03 2015-03-12      cookie7
2015-04 2015-04-12      cookie3
2015-04 2015-04-13      cookie2
2015-04 2015-04-13      cookie4
2015-04 2015-04-16      cookie4
2015-03 2015-03-10      cookie2
2015-03 2015-03-10      cookie3
2015-04 2015-04-12      cookie5
2015-04 2015-04-13      cookie6
2015-04 2015-04-15      cookie3
2015-04 2015-04-15      cookie2
2015-04 2015-04-16      cookie1
GROUPING SETS
在一個GROUP BY查詢中,根據不同的維度組合進行聚合,等價於將不同維度的GROUP BY結果集進行UNION ALL

SELECT 
month,
day,
COUNT(DISTINCT cookieid) AS uv,
GROUPING__ID 
FROM lxw1234 
GROUP BY month,day 
GROUPING SETS (month,day) 
ORDER BY GROUPING__ID;
 
month      day            uv      GROUPING__ID
------------------------------------------------
2015-03    NULL            5       1
2015-04    NULL            6       1
NULL       2015-03-10      4       2
NULL       2015-03-12      1       2
NULL       2015-04-12      2       2
NULL       2015-04-13      3       2
NULL       2015-04-15      2       2
NULL       2015-04-16      2       2
 
 
等價於 
SELECT month,NULL,COUNT(DISTINCT cookieid) AS uv,1 AS GROUPING__ID FROM lxw1234 GROUP BY month 
UNION ALL 
SELECT NULL,day,COUNT(DISTINCT cookieid) AS uv,2 AS GROUPING__ID FROM lxw1234 GROUP BY day
再如:

SELECT 
month,
day,
COUNT(DISTINCT cookieid) AS uv,
GROUPING__ID 
FROM lxw1234 
GROUP BY month,day 
GROUPING SETS (month,day,(month,day)) 
ORDER BY GROUPING__ID;
 
month         day             uv      GROUPING__ID
------------------------------------------------
2015-03       NULL            5       1
2015-04       NULL            6       1
NULL          2015-03-10      4       2
NULL          2015-03-12      1       2
NULL          2015-04-12      2       2
NULL          2015-04-13      3       2
NULL          2015-04-15      2       2
NULL          2015-04-16      2       2
2015-03       2015-03-10      4       3
2015-03       2015-03-12      1       3
2015-04       2015-04-12      2       3
2015-04       2015-04-13      3       3
2015-04       2015-04-15      2       3
2015-04       2015-04-16      2       3
 
 
等價於
SELECT month,NULL,COUNT(DISTINCT cookieid) AS uv,1 AS GROUPING__ID FROM lxw1234 GROUP BY month 
UNION ALL 
SELECT NULL,day,COUNT(DISTINCT cookieid) AS uv,2 AS GROUPING__ID FROM lxw1234 GROUP BY day
UNION ALL 
SELECT month,day,COUNT(DISTINCT cookieid) AS uv,3 AS GROUPING__ID FROM lxw1234 GROUP BY month,day
其中的 GROUPING__ID,表示結果屬於哪一個分組集合。

CUBE
根據GROUP BY的維度的所有組合進行聚合。

SELECT 
month,
day,
COUNT(DISTINCT cookieid) AS uv,
GROUPING__ID 
FROM lxw1234 
GROUP BY month,day 
WITH CUBE 
ORDER BY GROUPING__ID;
 
 
month  			    day             uv     GROUPING__ID
--------------------------------------------
NULL            NULL            7       0
2015-03         NULL            5       1
2015-04         NULL            6       1
NULL            2015-04-12      2       2
NULL            2015-04-13      3       2
NULL            2015-04-15      2       2
NULL            2015-04-16      2       2
NULL            2015-03-10      4       2
NULL            2015-03-12      1       2
2015-03         2015-03-10      4       3
2015-03         2015-03-12      1       3
2015-04         2015-04-16      2       3
2015-04         2015-04-12      2       3
2015-04         2015-04-13      3       3
2015-04         2015-04-15      2       3
 
 
 
等價於
SELECT NULL,NULL,COUNT(DISTINCT cookieid) AS uv,0 AS GROUPING__ID FROM lxw1234
UNION ALL 
SELECT month,NULL,COUNT(DISTINCT cookieid) AS uv,1 AS GROUPING__ID FROM lxw1234 GROUP BY month 
UNION ALL 
SELECT NULL,day,COUNT(DISTINCT cookieid) AS uv,2 AS GROUPING__ID FROM lxw1234 GROUP BY day
UNION ALL 
SELECT month,day,COUNT(DISTINCT cookieid) AS uv,3 AS GROUPING__ID FROM lxw1234 GROUP BY month,day

是CUBE的子集,以最左側的維度爲主,從該維度進行層級聚合。

比如,以month維度進行層級聚合:
SELECT 
month,
day,
COUNT(DISTINCT cookieid) AS uv,
GROUPING__ID  
FROM lxw1234 
GROUP BY month,day
WITH ROLLUP 
ORDER BY GROUPING__ID;
 
month  			    day             uv     GROUPING__ID
---------------------------------------------------
NULL             NULL            7       0
2015-03          NULL            5       1
2015-04          NULL            6       1
2015-03          2015-03-10      4       3
2015-03          2015-03-12      1       3
2015-04          2015-04-12      2       3
2015-04          2015-04-13      3       3
2015-04          2015-04-15      2       3
2015-04          2015-04-16      2       3
 
可以實現這樣的上鑽過程:
月天的UV->月的UV->總UV
--把month和day調換順序,則以day維度進行層級聚合:
 
SELECT 
day,
month,
COUNT(DISTINCT cookieid) AS uv,
GROUPING__ID  
FROM lxw1234 
GROUP BY day,month 
WITH ROLLUP 
ORDER BY GROUPING__ID;
 
 
day  			      month              uv     GROUPING__ID
-------------------------------------------------------
NULL            NULL               7       0
2015-04-13      NULL               3       1
2015-03-12      NULL               1       1
2015-04-15      NULL               2       1
2015-03-10      NULL               4       1
2015-04-16      NULL               2       1
2015-04-12      NULL               2       1
2015-04-12      2015-04            2       3
2015-03-10      2015-03            4       3
2015-03-12      2015-03            1       3
2015-04-13      2015-04            3       3
2015-04-15      2015-04            2       3
2015-04-16      2015-04            2       3
 
可以實現這樣的上鑽過程:
天月的UV->天的UV->總UV
(這裏,根據天和月進行聚合,和根據天聚合結果一樣,因爲有父子關係,如果是其他維度組合的話,就會不一樣)
這種函數,需要結合實際場景和數據去使用和研究,只看說明的話,很難理解。

 

參考鏈接

http://lxw1234.com/archives/2015/04/193.htm

https://blog.csdn.net/dingchangxiu11/article/details/83145151?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-12.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-12.nonecase

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