轉自:https://www.cnblogs.com/cc11001100/p/9043946.html
Hive中collect相關的函數有collect_list和collect_set。
它們都是將分組中的某列轉為一個數組返回,不同的是collect_list不去重而collect_set去重。
做簡單的實驗加深理解,創建一張實驗用表,存放用戶每天點播視頻的記錄:
create table t_visit_video ( username string, video_name string ) partitioned by (day string) row format delimited fields terminated by ',';
在本地文件系統創建測試數據文件:
張三,大唐雙龍傳
李四,天下無賊
張三,神探狄仁傑
李四,霸王別姬
李四,霸王別姬
王五,機器人總動員
王五,放牛班的春天
王五,盜夢空間
將數據加載到Hive表:
load data local inpath '/root/hive/visit.data' into table t_visit_video partition (day='20180516');
按用戶分組,取出每個用戶每天看過的所有視頻的名字:
select username, collect_list(video_name) from t_visit_video group by username ;
但是上面的查詢結果有點問題,因為霸王別姬實在太好看了,所以李四這家伙看了兩遍,這直接就導致得到的觀看過視頻列表有重復的,所以應該增加去重,使用collect_set,其與collect_list的區別就是會去重:
select username, collect_set(video_name) from t_visit_video group by username;
李四的觀看記錄中霸王別姬只出現了一次,實現了去重效果。
突破group by限制
還可以利用collect來突破group by的限制,Hive中在group by查詢的時候要求出現在select后面的列都必須是出現在group by后面的,即select列必須是作為分組依據的列,但是有的時候我們想根據A進行分組然后隨便取出每個分組中的一個B,代入到這個實驗中就是按照用戶進行分組,然后隨便拿出一個他看過的視頻名稱即可:
select username, collect_list(video_name)[0] from t_visit_video group by username;
video_name不是分組列,依然能夠取出這列中的數據。