今天写了一下hive中map类型字段,如何在原有基础上在增加新的值。
代码如下(示例):
create table aa_test(
name string,
age int,
source map<string,string>
)
ROW FORMAT DELIMITED fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':';
代码如下(示例):
insert into aa_test(name,age,source) values('zhang',15,str_to_map('yuwen:100,shuxue:98,yingyu:88,wuli:89,huaxue:100'));
根据上图展示的结果,目前想得到的结果是在source字段原有数据的基础上,增加"name":"zhang:,“age”:"14"这样的结果。sql如下:
select name,age,
str_to_map(CONCAT_WS(',',collect_set(concat(source_key,":",source_value)),collect_set(concat("name",":",name)),collect_set(concat("age",":",age))),",",":")
from
(select name,age,keys_1 source_key,value_1 source_value from aa_test a
LATERAL VIEW explode(a.source) b as keys_1,value_1) t
group by name,age;
#注释:
1. str_to_map(字符串参数, 分隔符1, 分隔符2)
使用两个分隔符将文本拆分为键值对。
分隔符1将文本分成K-V对,分隔符2分割每个K-V对。对于分隔符1默认分隔 符是 ',',对于分隔符2默认分隔符是 '='
2.CONCAT_WS()
如何指定参数之间的分隔符
使用函数CONCAT_WS()。
使用语法为:CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。但是CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。
3.CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。可以有一个或多个参数。
4. collect_set(col)
concat_ws常和collect_set和group by结合起来一起用
collect_set去除重复元素;collect_list不去除重复元素
collect_set(col)函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段。
hive中常存在先通过group by对一字段去重后,还需要对另一字段也去重,这时候就需要collect_set()。
5.explode()
explode()的功能是行转列.explode作用是处理map结构的字段
需要注意的是LATERAL VIEW explode(a.source) b as keys_1,value_1 这条语句中的b是虚表的名称,这个字段是必须要有的.
lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。
对hive中map类型的字段处理完成。