Hive分析窗口函數


  Hive中提供了越來越多的分析函數,用於完成負責的統計分析。

  今天簡單整理一下,以務以后自己快速查詢,也給看到的朋友作個參考。

  分析函數主要用於實現分組內所有和連續累積的統計。

 

一. AVG,MIN,MAX,和SUM

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

 

二. NTILE,ROW_NUMBER,RANK,DENSE_RANK

  1) NTILE

  NTILE(n),用於將分組數據按照順序切分成n片,返回當前切片值
  NTILE不支持ROWS BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
如果切片不均勻,默認增加第一個切片的分布

  2)ROW_NUMBER

  ROW_NUMBER() –從1開始,按照順序,生成分組內記錄的序列,比如,按照pv降序排列,生成分組內每天的pv名次。

  ROW_NUMBER() 的應用場景非常多,再比如,獲取分組內排序第一的記錄;獲取一個session中的第一條refer等。

  3)RANK和DENSE_RANK

  RANK() :  生成數據項在分組中的排名,排名相等會在名次中留下空位

  DENSE_RANK() : 生成數據項在分組中的排名,排名相等會在名次中不會留下空位

 

三. CUME_DIST,PERCENT_RANK

  1) CUME_DIST

  CUME_DIST 小於等於當前值的行數/分組內總行數
  比如,統計小於等於當前薪水的人數,所占總人數的比例

  2) PERCENT_RANK

  將當前行的值歸一化為0到1的值,其中全部(或者分組)的最大值對應1,最小值對應0,其他均勻分布在0到1之間。

 

四. LAG,LEAD,FIRST_VALUE,LAST_VALUE

  1)LAG

  LAG(col,n,DEFAULT) 用於統計窗口內往上第n行值
  第一個參數為列名,第二個參數為往上第n行(可選,默認為1),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)

  2)LEAD

  與LAG相反
  LEAD(col,n,DEFAULT) 用於統計窗口內往下第n行值
  第一個參數為列名,第二個參數為往下第n行(可選,默認為1),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)

  3)FIRST_VALUE

  取分組內排序后,截止到當前行,第一個值,(如果不指定分組,則返回第一行的值)

  4)LAST_VALUE

  取分組內排序后,截止到當前行,最后一個值

  如果不指定ORDER BY,則默認按照記錄在文件中的偏移量進行排序,會出現錯誤的結果

  如果想要取分組內排序后最后一個值,則需要變通一下,用FIRST_VALUE函數,然后按指定的排序字段倒排

 

五. GROUPING SETS,GROUPING_ID,CUBE,ROLLUP

  這幾個分析函數通常用於OLAP中,不能累加,而且需要根據不同維度上鑽和下鑽的指標統計,比如,分小時、天、月的UV數。

  1)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,(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

 

  2)GROUPING__ID

  其中的 GROUPING__ID,表示結果屬於哪一個分組集合

  3)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

 

  4)ROLLUP

  是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
(這里,根據天和月進行聚合,和根據天聚合結果一樣,因為有父子關系,如果是其他維度組合的話,就會不一樣)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM