hive中一些DML的操作
DML(数据操纵语言)主要指数据的增删查改
数据导入
有5种导入数据的方法,最常用的是 Load 和 Insert
Load
从文件系统中导入数据
load data [local] inpath '/xxxxxx' |
- local: 指本地文件系统,否则为HDFS
- overwrite: 指覆盖表中已有数据,否则表示追加
- partition: 表示上传到指定分区
Insert
通过查询语句导入数据
# 覆盖 |
As Select
查询语句中创建表并导入数据
create table if not exists tablename |
Location
创建表时通过Location指定数据的路径,再直接put数据到hdfs上
hive (default)> dfs -put /xxxxx /user/hive/warehouse/tablename; |
Import
只能导入export导出的数据
import table tablename partition(month='201909') from '/user/hive/warehouse/export/student'; |
数据导出
最常用的是 Insert 和 Hadoop
Insert
# 将数据导入本地(并格式化处理),不加local就是导入HDFS |
Hadoop
# hadoop命令导出 |
Export
这个导出的数据除了数据还有元数据,可用Import导入
hive > export table tablename to '/user/hive/warehouse/export/student'; |
数据清除
只能清除内部表的数据
hive > truncate table tablename; |
查询
查询的关键字较多,要知道它们的顺序(重点)
写的顺序:
select ... from ... join on ... where ... group by ... having ... order by ... limit ... |
执行顺序:大体思路是 限定(where),分组,限定(having),选择,排序
from -> join on -> where -> group by -> having -> select -> order by -> limit |
select…where…limit
# 简单查询 |
group by 和 having
group by 语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作
# 计算emp表每个部门的平均工资 |
where 作用在 分组(group by)和聚合(sum等)计算之前,选取哪些行,也就是在查询前筛选;having 对分组后计算的数据进行过滤。它只用于group by分组统计语句。
# 求每个部门的平均薪水大于2000的部门 |
join
Hive支持通常的SQL JOIN语句,但是只支持等值连接,不支持非等值连接。 且 连接谓词中不支持or。
这个非等值连接可以从以前学的reducejoin的流程思索原因,reducejoin是在shuffer时将数据按关联值相等的(on的条件)分为一组,再在reducer阶段进行处理。
# 合并员工表和部门表 |
排序
全局排序 Order By
全局排序,只一个Reducer。全排很明显最后生成一个总的排序文件,1个reducer
# 查询员工信息按工资降序排列 |
按reducer排序 sort by
每个reducer端都会做排序,出来的数据是有序的。假如有n个Reducer,就会生成n个有序文件。当n=1时,它就是Order By
。
扩展一波,Reducer个数默认按原始数据256M一个,当然也可手动设置其个数。
分区排序 Distribute By…Sort By
先分区,后排序。这个分区类型mapreduce的分区,多少个分区,就有多少个reduce任务,后面就生成多少个文件。说白了这个和上面的区别就是它通过Distribute By
指定怎么分区,即指定怎么分reducer。
# 设置reduce个数 |
分桶 Cluster By
当distribute by 和 sorts by 字段相同时,可以使用cluster by方式。但排序只能是升序排序。
可以从取名看出,我没用分桶排序。你可以理解 Cluster 就是把数据分区,然后每个分区生成一个文件,这样就好解释为啥只能升序排序,我理解它压根就不需要排序,只是把数据分到不同区就ok。
# 以下两种写法等价 |
细节一:来波小结理一下 分区表 分区排序 分桶(前两个分区意思截然不同)
partition(month='201909')
这个是分区表,针对的是数据的存储路径Distribute By...Sort By
这个是分区排序,和MR中的分区概念一样,多少个分区,就有多少个reduce任务,后面就生成多少个文件,分区之后对区里的数据进行排序。Cluster By
分桶,针对的是数据文件,将大的数据集分区。
所以将 Cluster By 理解为分区, Distribute By…Sort By 理解为分区排序,岂不美哉
细节二:注意导入数据到分桶中,要用insert,且 设置hive.enforce.bucketing=true
和 hive.enforce.bucketing=true
细节三:分桶抽样查询
select * from tablename tablesample(bucket x out of y on id);
x 表示从哪个bucket开始抽取
y 表示抽样间隔,共抽取 总数/y 个桶,且x的值必须小于等于y的值
举例:如果 x = 1, y = 4 ,共16个桶,那么将抽取16/4个桶,分别是 1、5、9、13
行转列、列转行
行转列:将不同行的聚合到一起
collect_set(col)
:函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总(不去重用list),产生array类型字段
例子:
select |
列转行:将列拆分成多行。
explode(col)
将hive一列中复杂的array或者map结构拆分成多行
LATERAL VIEW udtf(expression) tableAlias AS columnAlias
用于和split, explode等UDTF一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
例子:
select |
窗口函数
基本结构:函数 over(范围) 。用前面的函数处理over中的规定的数据
除了count、sum等一些常用函数,还有只能配合over使用的函数:
lag(col,n)
:往前第n行数据lead(col,n)
:往后第n行数据ntile(n)
:给数据编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。rank()
排序相同时会重复,总数不会变,如12225668dense_rank()
排序相同时会重复,总数会减少,如12223445row_rank()
单纯顺序计算,如12345678
over里面可以规定窗口范围:
()
:全部数据(partition by xxx order by xxx)
:分区有序(rows between xxxx and xxxx)
:手动指定范围current row
:当前行n preceding
:往前n行数据n following
:往后n行数据unbounded preceding
: 从起点开始unbounded following
: 到终点结束
一些例子:
business.name business.orderdate business.cost |