狂甩酷拽吊炸天
分类: NOSQL
2018-01-18 16:42:07
例如,定义表:
create table example (
device_id string,
login_ip array<string>,
user_info map<string,array<string>>
address structstring,city:string,state:string>
)
row format delimited
fields terminated by '\001' collection items terminated by '\002' map keys terminated by '\003' lines terminated by '\n' stored as RCFile;
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
在hive环境下运行,即可创建该管理表(区分外部表),如果有必要,可以直接使用load data加载数据。
collect_set(col)函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段。例如,如下数据记录,要统计每种no下的score,这里就可以配合group by 产生奇效。
no score 1 2 1 3 1 3 2 2 2 4 2 4 ......
直接对no分组后对score进行collect_set操作,如下:
select no,collect_set(score) from tablss group by no;
这样,就实现了将列转行的功效,但是注意只限同列基本数据类型,函数只能接受一列参数。
有以下表
id | name |
---|---|
1001 | A |
1001 | B |
1001 | C |
实现以下功能
id | name |
---|---|
1001 | A,B,C |
即按照id 进行group by,将每个id的name组成一个list放到name字段中。
若name中有重复的值,可以用collect_set函数进行去重
collect_list函数返回的类型是array< ? >类型,?表示该列的类型
怎么转为string类型?
我们可以使用concat_ws函数,但是该函数仅支持string和array< string > 所以对于该列不是string的列,先转为string
最终实现了我们需要的输出结果
concat_ws函数的意思是用逗号将所有的string组合到一起,用逗号分割显示
上面代码的结果就是
A,B
explode(array)函数接受array类型的参数,其作用恰好与collect_set相反,实现将array类型数据行转列,例如,上述记录列转行后的形式如下:
no score_set 1 [2,3] 2 [2,4]
假设这样的数据类型以分区表存储,你要统计一段时间类no=1下的去重score,那么该怎么办了?这里可配合使用lateral view首先实现列转行的功能,如下所示:
select no,score from tablaa lateral view explode(score_set) xxx as score;
注:xxx代表虚表名称,不能缺少。
进一步深化上述代码解决统计一段时间的去重值,可写为:
select no,collect_set(score) from tablaa lateral view explode(score_set) xxx as score group by no;
这样,将两个函数结合实现了行转列或列转行的妙用。
列转行可用到explode
表示1,2,3,4拼接起来,然后再用逗号分隔成列,应用到表中如下面所示