一:前言
在某些场景下比如报表的产出,为了更加易于理解,往往会行列互置这样显示,又或者我们需要将某个相同键的值,所属的属性进行合并显示,这样都会用到行转列或者列转行。
二:行转列如何实现
使用lateral view结合explode这样的UDTF进行实现,由于explode的参数要求是list()或者array()类型,所以往往还需要用到spilt函数进行分割。
以下是一个演示:
select
split(detail,',')[0] as uname
,split(detail,',')[1] as create_time
,split(detail,',')[2] as pv
from
(
select
concat('测试用户,2019-10-02,7
#测试用户,2019-10-05,4
#测试用户,2019-10-07,5
#测试用户,2019-10-03,6
#测试用户,2019-10-04,3
#测试用户,2019-10-01,3
#测试用户,2019-10-06,4') as ct_str
) t
lateral view explode(split(ct_str,'#')) t2 as detail;
以上()当中为了演示只有select语句,正常来讲是一条正常的sql,目的是将需要分割成多行的数据进行整合到一行当中去,然后使用explode处理,split(ct_str,'#')的目的是将ct_str按照#分割成多行,explode这个UDTF可以返回0行或者大于1行的记录,所以说explode和split往往结合起来使用,然后使用lateral view将多行结果组合成一个支持别名的虚拟表t2和列detail。然后在外层继续使用split函数将返回行进一步分割,这样就实现了行转列了。
三:列转行如何实现
一般使用group by column..+concat_ws+collect_list/collect_set来实现
-- 准备数据
select * from dw_tmp.window_function_temp;
select
uname
,concat_ws(',',collect_list(cast(pv as string)))
from dw_tmp.window_function_temp
GROUP BY uname;
select
uname
,concat_ws(',',collect_set(cast(pv as string)))
from dw_tmp.window_function_temp
GROUP BY uname;