1、load 数据
-
1.1、基本语法:
load data [local] inpath 'path' [overwrite] into table 'table_name' partition(partitionfield='xx');
-
1.2、本质: 就是将数据从INPATH所指定的路径拷贝或者移动到表或者区文件夹中
如果数据是在本地 LOCAL INPATH ,数据是拷贝 如果数据是在HDFS上, INPATH ,数据是移动
2、动态分区
-
2.1、含义: 动态分区就是可以根据select查询出来的结果数据中的一个字段的值不同,而插入另一个表中不同的分区
-
2.2、例子:
先创建一个t_stu普通的学生详情表 t_a create table t_a(sno int,sname string,sex string) partitioned by(sage string); 创一个学生基本信息表 t_stu_baseinfo create table t_stu_baseinfo(sno int,sname string,sex string) partitioned by(sage string); 从详情表中查询若干字段数据插入t_stu_baseinfo表中,并且根据age不同而放入不同的分区 注意:要使用动态分区,必须先开启动态分区参数 hive> set hive.exec.dynamic.partition.mode=nonstrict; hive> insert into table t_a partition(sage) select sno,sname,sex,sage from t_b; 结果观察 hive> show partitions t_stu_baseinfo; OK sage=17 sage=18 sage=19 sage=20 sage=21 sage=22 sage=23
3、关于JOIN
-
3.1、join类型:
通用:INNER JOIN(JOIN) , LEFT JOIN(LEFT OUTER JOIN) ,RIGHT JOIN(RIGHT OUTER JOIN),full outer join HIVE专用:left semi join 左半连接
-
3.2、例子:
准备数据 1,a 2,b 3,c 4,d 7,y 8,u 2,bb 3,cc 7,yy 9,pp
-
3.3、建表:
create table a(id int,name string) row format delimited fields terminated by ','; create table b(id int,name string) row format delimited fields terminated by ',';
-
3.4、导入数据:
load data local inpath '/root/hivedata/a.txt' into table a; load data local inpath '/root/hivedata/b.txt' into table b; 实验: ** inner join ==> 只展示两边对的上的 select a.*,b.* from a inner join b on a.id=b.id; +-------+---------+-------+---------+--+ | a.id | a.name | b.id | b.name | +-------+---------+-------+---------+--+ | 2 | b | 2 | bb | | 3 | c | 3 | cc | | 7 | y | 7 | yy | +-------+---------+-------+---------+--+ **left join ==> a表全部展示,右边的如果没有置空 select * from a left join b on a.id=b.id; +-------+---------+-------+---------+--+ | a.id | a.name | b.id | b.name | +-------+---------+-------+---------+--+ | 1 | a | NULL | NULL | | 2 | b | 2 | bb | | 3 | c | 3 | cc | | 4 | d | NULL | NULL | | 7 | y | 7 | yy | | 8 | u | NULL | NULL | +-------+---------+-------+---------+--+ **right join ==> b表全部展示,左边没有置空 select * from a right join b on a.id=b.id; +-------+---------+-------+---------+--+ | a.id | a.name | b.id | b.name | +-------+---------+-------+---------+--+ | 2 | b | 2 | bb | | 3 | c | 3 | cc | | 7 | y | 7 | yy | | NULL | NULL | 9 | pp | +-------+---------+-------+---------+--+ **左右连接 ==> 全部都展示出来 select * from a full outer join b on a.id=b.id; +-------+---------+-------+---------+--+ | a.id | a.name | b.id | b.name | +-------+---------+-------+---------+--+ | 1 | a | NULL | NULL | | 2 | b | 2 | bb | | 3 | c | 3 | cc | | 4 | d | NULL | NULL | | 7 | y | 7 | yy | | 8 | u | NULL | NULL | | NULL | NULL | 9 | pp | +-------+---------+-------+---------+--+ **hive中的特别左半链接 semi join ==> 相当于左链接中,全部对上的 select * from a left semi join b on a.id = b.id; 效果相当于左连接结果中的左表连接成功的部分 +-------+---------+--+ | a.id | a.name | +-------+---------+--+ | 2 | b | | 3 | c | | 7 | y | +-------+---------+--+ 相当于 select * from a where a.id exists(select b.id from b); 在hive中效率极低 --------------------------------------------------------------------------------
4、关于分组查询
区别于分桶查询,分组查询的结果,一组只有一条记录返回。分桶查询只是将数据按照hash % reducer分开到不同的桶,数据总数前后不变。每个桶里面有个人的记录,而且每个人还可能有多条数据。 例如:每个人每个月的上网流量。分桶后,小明的所有上网信息肯定在同一个桶里面,这个桶里面可能还包含小冬、老张的数据。
+-----------------------+--------------------+---------------------+--+
| usermag_tab.username | usermag_tab.month | usermag_tab.salary |
+-----------------------+--------------------+---------------------+--+
| A | 2015-01 | 5 |
| A | 2015-01 | 15 |
| B | 2015-01 | 5 |
| A | 2015-01 | 8 |
| B | 2015-01 | 25 |
| A | 2015-01 | 5 |
| A | 2015-02 | 4 |
| A | 2015-02 | 6 |
| B | 2015-02 | 10 |
| B | 2015-02 | 5 |
+-----------------------+--------------------+---------------------+--+
首先需要设置一些reduce的数量,默认是1
set mapreduce.job.reduces=5;
需要对这组数据按照每个用户、每个月的访问量进行汇总。
select username,month,sum(salary) as salary from usermag_tab group by username,month;
如果需要累计每个用户的访问次数,不按月分,那么可以如下:
select username,max(month) as month,sum(salary) as salary from usermag_tab group by username;
注意:如果写成如下会报错,因为month会有多个值,必须选择其中一个
select username,month,sum(salary) as salary from usermag_tab group by username;
分组查询,没法做到去重,因为返回来的其他值有多个,没法一一对应,这时候一般使用row_number、rank、dense_rank函数为每条数据加上一个值后,在根据值的大小求topN。如果是top1就实现了排重功能
5、关于多重插入
from student
insert into table student_p partition(part='a')
select * where Sno<95011;
insert into table student_p partition(part='b')
select * where Sno>95011;
6、关于导出数据到本地
insert overwrite local directory '/home/hadoop/student.txt' select * from student;
7、本地模式(本地跑demo的时候可以用)
set hive.exec.mode.local.auto=true;