Hive第五天——Hive函數(表生成函數:行轉列)


本文部分參考自:https://blog.csdn.net/qq_23897391/article/details/98724777


Hive第五天——Hive函數

自己的話:千里之行,始於足下。

每天都要保持前進,我勢必要有強勁的實力,再跟明天的自己問好。


表生成函數(行轉列)

一、表生成函數簡介

在Hive中,所有的表生成函數,包括用戶自定義的和內置的,都統稱爲用戶自定義表生成函數(user defined table generating functions),簡稱UDTF。本文只介紹Hive自帶的內置表生成函數。


二、函數功能演示

1.explode(ARRAY)

(1)功能:

返回n行,每行對應數組中的一個元素。

(2)舉例:
hive (app)> select explode(array(1,2,3,4));
OK
col
1
2
3
4

<1>編輯數據:

vi sutdent.txt
1,zhangsan,數學:語文:英語:生物
2,lisi,數學:語文
3,wangwu,化學:計算機:java

<2>創建表:

hive> create table t_xuanxiu(uid string,name string,kc array<string>)
	>row format delimited
	>fields terminated by ','
	>collection items terminated by ':';

<3>加載數據並查看:

hive> load data local inpath "/home/student.txt" into table t_xuanxiu;
hive> select uid,name,kc[0] from t_xuanxiu;  #kc[0]查看的是數組的第一個元素

在這裏插入圖片描述
<4>將一個數組變成列:

hive> select explode(kc) from t_xuanxiu where uid=1;

在這裏插入圖片描述

2.explode(MAP)

(1)功能:

返回n行兩列,每行對應每個map鍵-值,第一列是map的鍵,第二列是map的值。(不常用)

(2)舉例:
hive (app)> select explode(map(1,2,3,4));
OK
key	value
1	2
3	4

3.json_tuple(jsonStr, k1, k2, …)

(1)功能:

從一個JSON字符串中獲取多個key對應的value並作爲一個元組返回。

(2)舉例:

具體用法見 Hive函數(JSON解析函數)

4.parse_url_tuple(url, p1, p2, …)

(1)功能:

返回從URL中抽取指定N部分的內容並作爲一個元組返回,參數url是URL字符串,而參數p1,p2,…是要抽取的部分。

(2)舉例:

具體用法見 Hive函數(URL解析函數)

還有許多不常用的函數,很少碰見,就不詳述了。


三、表生成函數必備:lateral view

UDTF有一個很大的限制,在使用UDTF時,select後面只能跟UDTF,不能跟其他任何字段,否則會報錯,如下:

hive (app)> select 1 as flag,explode(array(1,2,3,4));
 
FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions

lateral view就是爲了解決在select使用UDTF做查詢過程中,查詢只能包含單個UDTF,不能包含其他字段、以及多個UDTF的問題。

lateral view 會將UDTF拆分成多行的結果放到一個支持別名的虛擬表中,然後這個虛擬表會和輸入行進行join 來達到連接UDTF外的select字段的目的。

1.lateral view語法

select 
列別名1[ ,列別名2,列別名3……] 
from 表名 lateral view udtf(expression) 虛擬表別名 as 列別名1[ ,列別名2,列別名3……]

lateral view跟在from後面,然後跟要使用的UDTF,爲生成的虛擬表起一個表別名,不寫會報錯。然後跟as 列別名,有些UDTF會產生多個列,所以有時要跟多個列別名,比如JSON和URL解析的例子。

2. 應用:行轉列

(1)需求:

現有數據如下:

a 1,2,3
b 4,5,6

想將數據格式轉爲:

a 1
a 2
a 3
b 4
b 5
b 6

這種展現格式的轉換操作就叫做行轉列。

(2)舉例1:

<1>新建test.txt文件,輸入上文的兩列數據,以空格分隔

[root@hadoop ~]# vim test.txt 
 
a 1,2,3
b 4,5,6

<2>在hive中新建表temp_test6,將test文件中的數據插入,查看數據

CREATE TABLE temp_test6 (
      shop STRING
      ,uid_array STRING
      ) row format delimited fields terminated BY ' ';
 
 
load data local inpath '/root/test.txt' into table temp_test6;
 
select * from temp_test6;
 
temp_test6.shop	temp_test6.uid_array
a	1,2,3
b	4,5,6

<3>使用lateral view explode和split函數行轉列

首先使用split函數對uid_array進行切割,返回一個數組,然後使用lateral VIEW explode進行行轉列
 
SELECT shop
      ,uid   --這裏是下面生成的列別名
FROM temp_test6 lateral VIEW explode(split(uid_array, ',')) a AS uid;
 
shop	uid
a	1
a	2
a	3
b	4
b	5
b	6
(3)舉例2:

上面寫到的學生選修學科,學科在表中是一個數組
<1>需求:

1,zhangsan,數學
1,zhangsan,語文
1,zhangsan,英語
1,zhangsan,生物
2,lisi,數學
2,lisi,語文

id和拆分的array元素是對應的.我們應該如何進行連接呢?我們知道直接select id,explode()是不行的.這個時候就需要lateral view出廠了.
<2>使用lateral view和explode函數行轉列

hive>select uid,name,tmp.course from t_xuanxiu
	>lateral view explode(kc) tmp as course;

在這裏插入圖片描述
<3>解釋:
lateral view 將 explode(kc) 看成一個表是 tmp 就一個字段as course;

3.應用:求總聚合結果

舉例:

(1)新建test.txt文件,輸入上文的兩列數據,以空格分隔

[root@hadoop ~]# vim test.txt 
 
a 1
a 2
a 4
b 4
b 5
b 6

(2)在hive中新建表temp_test7,將test文件中的數據插入,查看數據。第一列shop是商店名,第二列uid代表來點用戶id。

CREATE TABLE temp_test7 (
      shop STRING
      ,uid STRING
      ) row format delimited fields terminated BY ' ';
 
 
load data local inpath '/root/test.txt' into table temp_test7;
 
select * from temp_test7;
 
temp_test7.shop	temp_test7.uid
a	1
a	2
a	4
b	4
b	5
b	6

(3)此時想一句HQL求出每個商店的來客數,以及兩個商店去重後的來客數。由於uid爲4的用戶同時出現在兩家商店,所以統計total維度時用戶數爲5。最終要得到如下結果:

a     3
b     3
total 5 

(4)使用lateral view explode實現,關鍵點在於構造一個array數組,將原本的聚合維度字段放入,然後任意自定義一個詞例如‘total’作爲總聚合的維度名稱,再自定義一個別名(這裏使用total_shop),代表包含total的字段名,聚合時使用新自定義的別名進行聚合,如下:

SELECT total_shop
      ,count(distinct uid) AS uid_num
FROM temp_test7 lateral VIEW explode(array(shop, 'total')) A AS total_shop
GROUP BY total_shop;
 
total_shop	uid_num
a	        3
b	        3
total	        5

(5)等價於:

SELECT shop
      ,count(DISTINCT uid) AS uid_num
FROM temp_test7
GROUP BY shop
 
UNION ALL
 
SELECT 'total' AS shop
      ,count(DISTINCT uid) AS uid_num
FROM temp_test7;
 
total_shop	uid_num
a	        3
b	        3
total	        5

這就是Hive函數中的表生成函數,主要用於行轉列

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