GROUPING SETS,GROUPING__ID,CUBE,ROLLUP
這幾個分析函數通常用於OLAP中,不能累加,而且需要根據不同維度上鑽和下鑽的指標統計,比如,分小時、天、月的UV數。
Hive版本爲 apache-hive-0.13.1
數據準備:
- 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
- 等價於
- 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;
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
- 等價於
- 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 month, day
- 等價於
- SELECT month,day,COUNT(DISTINCT cookieid) AS uv,GROUPING__ID
- FROM lxw1234
- GROUP BY month,day
- grouping sets((),month,(month,day))
- ORDER BY GROUPING__ID;
- --把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
- (這裏,根據天和月進行聚合,和根據天聚合結果一樣,因爲有父子關係,如果是其他維度組合的話,就會不一樣)
這種函數,需要結合實際場景和數據去使用和研究,只看說明的話,很難理解。
官網的介紹: https://cwiki.apache.org/confluence/display/Hive/Enhanced+Aggregation%2C+Cube%2C+Grouping+and+Rollup