Group By 語法
groupByClause: GROUP BY groupByExpression (, groupByExpression)* groupByExpression: expression groupByQuery: SELECT expression (, expression)* FROM src groupByClause?
簡單例子
為了計算表的行數:
SELECT COUNT(*) FROM table2;
根據性別,計算去重用戶數,可以寫下面的查詢
INSERT OVERWRITE TABLE pv_gender_sum SELECT pv_users.gender, count (DISTINCT pv_users.userid) FROM pv_users GROUP BY pv_users.gender;
同時可以做多個聚合操作,但是,不能有兩個聚合操作有不同的DISTINCT列。下面的語句是合法的:
INSERT OVERWRITE TABLE pv_gender_agg SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(*), sum(DISTINCT pv_users.userid) FROM pv_users GROUP BY pv_users.gender;
但是,下面的查詢是不允許的。不允許在同一個查詢,有多個DISTINCT表達式
INSERT OVERWRITE TABLE pv_gender_agg SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(DISTINCT pv_users.ip) FROM pv_users GROUP BY pv_users.gender;
Select語句和group by字句
當使用group by字句,select語句,只能包含group by包含的列。當然,在select語句,可以有多個聚合函數(例如count)。看一下例子:
CREATE TABLE t1(a INTEGER, b INTGER);
一個關於上表的group by的查詢,可以是這樣:
SELECT a, sum(b) FROM t1 GROUP BY a;
上面的查詢可以工作,因為select字句包含a(group by表達式)和一個聚合函數(sum(b)).
但是,下面的查詢無法工作:
SELECT a, b FROM t1 GROUP BY a;
select語句有多余的列(b),它不包含在group by字句(而且它也不是聚合函數)。這是因為,如果表t1看起來像:
a b ------ 100 1 100 2 100 3
如果group的key是a,那么當group a=100時,b的值在hive中應該顯示多少?一種說法,它應該是第一個值或最低值,但我們都同意,有多種可能的選項。hive摒棄了這種猜測無效的SQL(HQL,要准確):有一列在select子句中,卻不包含在GROUP BY子句中。
高級特性
Multi-Group-By Inserts
簡單查詢或者聚合的輸出,可以發送到多個表甚至是hadoop的dfs文件(可以使用hdfs工具管理)。例子,如果伴隨着性別的細分,按年齡細分,人們需要根據這些,找到每個頁面的訪問量,使用下面的查詢,可以做到這一點:
FROM pv_users INSERT OVERWRITE TABLE pv_gender_sum SELECT pv_users.gender, count(DISTINCT pv_users.userid) GROUP BY pv_users.gender INSERT OVERWRITE DIRECTORY '/user/facebook/tmp/pv_age_sum' SELECT pv_users.age, count(DISTINCT pv_users.userid) GROUP BY pv_users.age;
GroupBy的Map端聚合
hive.map.aggr控制如何聚合,默認是false,如果設置為true,Hive將會在map端做第一級的聚合。這通常提供更好的效果,但是要求更多的內存才能運行成功。
set hive.map.aggr=true; SELECT COUNT(*) FROM table2;
翻譯自 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+GroupBy