hive中有四种排序方式
1、order by
全局排序,只能有一个reduce
desc 降序 asc 升序默认
2、sort by
类似在reduce中进行排序,所以一般需要多个reduce ,在每个reduce中进行排序,属于局部排序,而不是全局排序(局部有序)
场景: 当数据量很大时,不需要进行全局排序,只需进行局部排序
一般不单独使用,因为无法控制什么样的数据进入到同一个reduce中
一般配合distribute by 使用,分区排序就是指定什么样的数据会进入同一个reduce中
单独使用时,进入同一个 reduce 任务中的数据是随机的 就是每次计算的结果是一样的,但是进入每一个reduce 中的数据是随机的
# 设置reducer的个数
set mapreduce.job.reduces1=3;
3、distribute by
类似在 MapReduce 中的自定义分区(partition)
一般就是配合 sort by 使用
在使用的时候,不能是一个reduce,需要多个reduce
###什么样的数据会进行同一个reduce 呢
首先,这个分区不是很智能,使用的方式是:分区的字段的 ( hashcode % reduce的个数 ),计算值相等的,则进入同一个reduce;不会使用toString方式进行分区。
distribute by 必须写在sort by 的前面
4、cluster by
当distribute by 和 sort by 的字段相同时,可以使用Cluster by 进行替代
create table if not exists 表名(
name string,
gender string
)partition by (id int,...) # 分区字段不能在 () 中出现,但可以作为查询字段
row format delimited fields terminated by ',';
设置
# 将hive设置为非严格模式 在严格模式下,分区必须至少有一个是静态字段
set hive.exec.dynamic.partition.mode=nonstrict
eg:
create table if not exists emp(
name string,
gender string
)partition by(dept int)
row format delimited fields terminated by ',';
insert into table emp partition (dept)
select
name,
gender,
dept
from emp1;
eg:
create table if not exists emp(
name string,
gender string,
dept int
)clustered by(dept,...) into 3 buckets # dept 等字段必须来自表中 3 buckets 代表数据分为 3桶
row format delimited fields terminated by ',';
抽样查询
当数据量特别庞大的时候,想要了解数据,不需要通过查询全表数据来获取数据的情况
可以通过抽样查看
eg:
select id,name,gender from emp tablesample (bucket x out of y on id);
on:表示依据那个字段进行抽样
y:表示将根据按照on后面的字段分为y份儿
x:表示只要第x份
注:
必须满足 x <= y
FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck
将分组后的某个字段的所有数据 搜集到一行 ,是一个数组
collect_list 对收集后的数据不去重
collect_set 对收集后的数据去重
通常结合 concat_ws函数使用,对收集到的数据进行自定义拼接
eg:
select constellation,
blood_type,
concat_ws('|',collect_list(name))
from dep
group by
constellation,
blood_type;
select explode(array('A','B','C'));
select explode(array('A','B','C')) as col;
select tf.* from (select 0) t lateral view explode(array('A','B','C')) tf;
select tf.* from (select 0) t lateral view explode(array('A','B','C')) tf as col;
炸裂array类型的数据,会将其炸为一列数据
eg:
A
B
C
explode(map)
select explode(map('A',10,'B',20,'C',30));
select explode(map('A',10,'B',20,'C',30)) as (key,value);
select tf.* from (select 0) t lateral view explode(map('A',10,'B',20,'C',30)) tf;
select tf.* from (select 0) t lateral view explode(map('A',10,'B',20,'C',30)) tf as key,value;
炸裂map集合,会将map炸成两列 分别为key和对应的value
结果如下
key value
A 10
B 20
c 30
posexplode(array)
select posexplode(array('A','B','C'));
select posexplode(array('A','B','C')) as (pos,val);
select tf.* from (select 0) t lateral view posexplode(array('A','B','C')) tf;
select tf.* from (select 0) t lateral view posexplode(array('A','B','C')) tf as pos,val;
posexplode(array) 会将array炸成两列 第一列是行编号从0开始即值在数组中的索引值,第二列式array的每个值
eg:
pos val
0 A
1 B
2 c
nline (array of structs)
拆解结构体数据
select inline(array(struct('A',10,date '2015-01-01'),struct('B',20,date '2016-02-02')));
select inline(array(struct('A',10,date '2015-01-01'),struct('B',20,date '2016-02-02'))) as (col1,col2,col3);
select tf.* from (select 0) t lateral view inline(array(struct('A',10,date '2015-01-01'),struct('B',20,date '2016-02-02'))) tf;
select tf.* from (select 0) t lateral view inline(array(struct('A',10,date '2015-01-01'),struct('B',20,date '2016-02-02'))) tf as col1,col2,col3;
将结构体中的每个字段拆解到一行
eg:
col1 col2 col3
A 10 2015-01-01
B 20 2016-02-02