hive行列互轉

2021-10-03 18:16:04 字數 3188 閱讀 6338

先說行轉列是什麼意思啊,假設有這樣的資料,uid表示使用者,time表示時刻,event表示使用者這個時刻在幹什麼,我們儲存到資料庫中就是這樣的

uidtime

event

a09:01:00睜眼a

09:02:00

找手機a

09:03:00發呆a

09:04:00洗臉a

09:05:00刷牙a

09:06:00吃飯b

13:01:00

玩手機b

13:02:00發呆b

13:03:00

工作但是很明顯,這樣看起來會很累,我們希望可以直觀一點

uidstart_time

end_time

path

a09:00:00

09:06:00

[睜眼,找手機,發呆,洗臉,刷牙,吃飯,工作]

b13:01:00

13:03:00

[吃飯,玩手機,發呆,工作]

這個可以清楚的看到,我們把使用者的每一行的資料彙總到了一列中,即通常說的行轉列

那麼用sql怎麼實現呢

select uid,

min(

time

)as start_time,

max(

time

)as end_time

,concat_ws(

',',collect_list(evnet)

)as path

from t_user_time_event

group

by uid

非常的簡單,我們通過group by對使用者進行聚合,collect_list把使用者的事件放到乙個陣列中,然後使用concat_ws進行連線,這樣就可以得到使用者的路徑了

說明:collect_list 不去重,collect_set 去重。 evnet的資料型別要求是string

uid

path

a09:01:00_睜眼,09:02:00_找手機,09:03:00_發呆,09:04:00_洗臉,09:05:00_刷牙,09:06:00_吃飯

b13:01:00_玩手機,13:02:00_發呆,13:03:00_工作

可以看到兩個使用者,後面是這個使用者在某個時刻做的事情,我們想要path這一列轉成行

uidtime

event

a09:01:00睜眼a

09:02:00

找手機a

09:03:00發呆a

09:04:00洗臉a

09:05:00刷牙a

09:06:00吃飯b

13:01:00

玩手機b

13:02:00發呆b

13:03:00

工作是的,沒錯,就是上面的那個case,這該怎麼搞呢?

select uid

,split(time_event,

'_')[0

]astime

,split(time_event,

'_')[1

]as event

from t_user_path

lateral view explode(split(path,

',')

) t as time_event

有點複雜,可以分開來講

split就是把路徑切割成陣列

split(path,

',')

explode列表中的每個元素生成一行

explode(array)

--列表中的每個元素生成一行

explode(map)

--map中每個key-value對,生成一行,key為一列,value為一列

select explode(split(path,

',')

)as time_event

from t_user_path

得到的結果就是

time_event

09:01:00_睜眼

09:02:00_找手機

09:03:00_發呆

09:04:00_洗臉

09:05:00_刷牙

09:06:00_吃飯

13:01:00_玩手機

13:02:00 _發呆

13:03:00_工作

然後再把使用者給關聯上

select uid,explode(split(path,

',')

)as time_event

from t_user_path

但是這樣就會存在問題,因為explode函式存在的侷限性

不能關聯原有的表中的其他字段。

不能與group by、cluster by、distribute by、sort by聯用。

不能進行udtf巢狀。 不允許選擇其他表示式。

也就是是說,explode解析後不能關聯到咱們的uid,這肯定是不行的,我們要分析的是不同使用者的行為。因此需要lateral view。

lateral view udtf(expression) tablealias as columnalias (

',' columnalias)

*

lateral view與使用者定義的表生成函式(如explode())一起使用。正如在內建的表生成函式中提到的,udtf為每個輸入行生成零個或多個輸出行。lateral view首先將udtf應用於基表的每一行,然後將產生的輸出行連線到輸入行,形成乙個具有提供的表別名的虛擬表。

注:lateral view通常和udtf一起出現,為了解決udtf不允許在select欄位的問題

這是什麼意思呢,據我不完全猜測,lateral view把explode解析的行暫存為乙個虛擬表,這個虛擬表呢與被select的字段進行join,然後得到最終的結果。

hive之explode

hive explode lateral view 用法

hive collect、explode函式詳解(包括concat、lateral view)

Hive學習筆記 行列互轉

當某一維度或多維度組合下出現多行資料,如何將其聚合至一行進行儲存?表名 tbl student score 字段 stu id 學號 stu name 姓名 subject 學科 score 分數 學號姓名 學科分數 1001 張三數學 991001 張三語文 601001 張三英語 701002 ...

sql 行列互轉

1 行轉列 現有資料 期望資料 1.1建表建資料 if object id temp 20170701 u is not null drop table temp 20170701 create table temp 20170701 id int primary key identity 1,1 ...

Hive 行列轉換

在京東眾多業務中,業務充滿了複雜性和挑戰性,因為業務的靈活性,很多資料都儲存成xml和json格式資料,這就要求下游資料分析師們需要對其做解析後方可使用 在眾多操作中 有一種是需要對資料做行列轉換操作。資料結構 create external table jd row to column jd id...