一、表的创建(外部表和内部表)

1、内部表与外部表的区别

外部表:hive中删除外部表时,数据不会被删除,即hive不会控制外部表数据的生命周期

内部表(管理表):hive中删除内部表时,数据会被删除掉,即hive会控制内部表数据的生命周期。

查询表的详情

desc formatted student5;

删除表:drop table student;

对于一个公司来说,数据非常重要,原始数据会放在外部表还是管理表中?外部表

2、创建表的方式(三种)

方式一:(普通创建表)(最常用的一种)

create [external] table student(

id int,

name string

)

row format delimited fields terminated by '\t'

stored as textfile      //存储类型

location '/user/zkpk/input';   //存储位置

方式二:(根据查询结果创建表)关键字:as select

create table student2 as select id,name from student;

方式三:(复制表的结构,不复制数据)关键字:like

create table student3 like student;

二、分区表

1、创建分区表,关键字:partitioned by

语法:create table student(

id int,

name string

)

partitioned by(month string)

row format delimited fields terminated by '\t';

2、分区表中导入数据

load data local inpath '/home/zkpk/datas/student.txt' into table student partition(month='202203');

3、查询分区表

select * from student where month='202203';

联合查询(查询二月份和三月份的数据)关键字:union

select * fron student where month='202202'

union select * from student where month='202203';

4、创建分区表的意义:减少查询数据,提高查询效率。

2022年3月3日内容:

一、分区表的操作

5、修改分区表(增加分区),关键字:alter...add

增加一个分区:

alter table dept_partition add partition(month='202204');

增加多个分区,分区间用空格隔开

alter table dept_partition add partition(month='202205') partition(month='202206');

6、删除分区,关键字:alter...drop

删除一个分区

alter table dept_partition drop partition(month='202206');

删除多个分区,删除的分区间用逗号隔开

alter table dept_partition drop partition(month='202204'),partition(month='202205');

7、查询分区

show partitions dept_partition;

二、创建二级分区:

create table dept_partition2(

deptno int,

dname string,

loc string

)

partitioned by(month string,day string)

row format delimited fields terminated by '\t';

二级分区表中导入数据

load data local inpath '/home/zkpk/datas/dept.txt' into table dept_partition2

partition(month='202203',day='02');

三、分区表关联数据(三种)

方式一:上传数据后修复分区 msck repair table +表名

1、创建目录

hive(default)>dfs -mkdir -p /user/hive/warehouse/student2/month=202203/day=03;

2、hive中创建表student2

hive(default)>create table student2(

id int,

name string

)

partitioned by(month string,day string)

row format delimited fields terminated by '\t';

3、上传数据

hive(default)>dfs -put /home/zkpk/datas/student.txt /user/hive/warehouse/student2/month=202203/day=03;

4、查询数据(查不到)

hive(default)>select * from student2;

5、修复分区

hive(default)>msck repair table student2;

 方式二:上传数据后添加分区 alter table +表名+add partition(month string)

 1、创建目录

 [zkpk@master ~]$hadoop fs -mkdir -p /user/hive/warehouse/dept_partition3/month=202203/day=03

 2、hive中创建表dept_partition3

 hive(default)>create table dept_partition3(

 deptno int,

 dname string,

 loc string

 )

 partitioned by(month string,day string)

 row format delimited fields terminated by '\t';

 3、上传数据

 [zkpk@master ~]$hadoop fs -put /home/zkpk/datas/dept.txt /user/hive/warehouse/dept_partition3/month=202203/day=03

 4、查询数据,查不到

 hive(default)>select * from dept_partition3;

 5、添加分区后可以查到数据

 hive(default)>alter table dept_partition3 add partition(month='202203',day='03');

 hive (default)> dfs -put /home/zkpk/datas/student.txt /user/zkpk/input;

[zkpk@master ~]$ hadoop fs -put /home/zkpk/datas/student.txt /user/zkpk/input

上述两条命令结果一样

 方式三:通过load加载数据,不需要修复或者添加分区 load data local inpath +'本地路径'

 1、创建目录

hive(default)>dfs -mkdir -p /user/hive/warehouse/dept_partition4/month=202203/day=03;

2、hive中创建表dept_partition4

hive(default)>create table dept_partition4(

deptno int,

dname string,

loc string

)

partitioned by(month string,day string)

row format delimited fields terminated by '\t';

3、通过load加载数据

hive(default)>load data local inpath '/home/zkpk/datas/dept.txt' into table dept_partition4

partition(month='202203',day='03');

4、可以直接查询数据

hive(default)>select * from dept_partition4;

四、数据的导入(五种)

1、通过load向hive表中导入数据

1)在hdfs上创建目录

dfs -mkdir -p /user/zkpk/input;

2)上传数据到hdfs

dfs -put /home/zkpk/datas/student.txt /user/zkpk/input

3)hive中创建student3

create table student3(

id int,

name string

)

row format delimited fields terminated by '\t';

4)把hdfs目录/user/zkpk/input下的数据加载到hive表中(hdfs上数据会被剪切走)

load data inpath '/user/zkpk/input' into table student3;

把本地数据加载到hive表中(本地数据复制走,不会被剪切)

load data local inpath '/home/zkpk/datas/student.txt' into table student3;

加载数据时加上overwrite表示原有hive表中的数据会被覆盖,如果不加则表示追加

load data local inpath '/home/zkpk/datas/student.txt' overwrite into table student3;

2、通过查询语句向表中国插入数据,关键字:insert(三种)

1)向表中插入一条数据

insert [overwrite] into table student3 values(1004,"lisi");(普通表)

insert [overwrite] into table student2 partition(month='202203') values(1004,"lisi");(分区表)

2)通过查询表向表中插入数据(表是提前创建好的)

create table student1(

id int,

name string

)

row format delimited fields terminated by '\t';

3)基本查询插入数据:向表中插入数据,如果加上overwrite则表示覆盖

insert into table student4 select id,name from student3;(普通表)

insert overwrite table student4 select id,name from student3;

insert into table student2 partition(month='202201') select id,name from student;(分区表)

4)多模式插入数据

from student3

insert [overwrite] into table student1 select id,name (普通表)

insert [overwrite] into table student4 select id,name;

一张表中插入数据,另一张表中是覆盖原有数据

from student3

insert [overwrite] into table student1 select id,name

insert [overwrite] overwrite table student4 select id,name;

from student

insert overwrite table student2 partition(month='202201') select id,name

insert into table student2 partition(month='202202') select id,name;(分区表)

3、查询语句中创建表并加载数据,关键字:as select

create table student4 as select id,name from student;

注意:student是分区表,但是student4是普通表

4、通过location指定加载路径(location指定的位置可以是hdfs的任意位置)

1)创建表

create table if not exists student6(

id int,

name string

)

row format delimited fields terminated by '\t'

location '/student6';

2)上传数据

dfs -put /home/zkpk/datas/student.txt /student6

3)在hive中查询

select * from student6;

5、通过import导入数据

import导入的数据必须是export导出的数据

二、导出数据(四种)

1、insert导出数据

将hive中表student4的数据导出到本地

insert overwrite local directory '/home/zkpk/datas/export/student'

select * from student4;

将导出数据格式化

insert overwrite local directory '/home/zkpk/datas/export/student'

row format delimited fields terminated by '\t'

select * from student4;

通过insert将数据导出到hdfs

insert overwrite directory '/user/zkpk/input/student4'

row format delimited fields terminated by '\t'

select * from student;

注意:1)insert既可以导入数据也可以导出数据。

      2)insert导入数据可以是覆盖也可以是追加(insert overwrite或者insert into)

         但是insert导出数据时只有覆盖,没有追加(insert overwrite)。

       3)导出到hdfs的数据不能格式化。

2、通过hadoop命令导出数据

dfs -get /user/hive/warehouse/student /home/zkpk/datas/export/student1;

dfs -get /user/hive/warehouse/student4 /home/zkpk/datas/export/student4;

3、通过hive shell 命令导出数据

bin/hive -e 'select * from student4;' > /home/zkpk/datas/export/student2(普通表)

bin/hive -e 'select * from student;' > /home/zkpk/datas/export/student3(分区表)

4、通过export导出数据

export table student4 to '/user/zkpk/student4';(普通表)

import table student2 from '/user/zkpk/student4';

注意:1)student2 不用需要提前创建。

      2)导入数据的表和导出数据的表必须一致。

import table student3 from '/student7';

FAILED: SemanticException [Error 10027]: Invalid path

注意:1)import导入的数据必须是export导出的数据,否则会报错

          2)导出数据和导入数据的表必须一致

        3)导出数据export...to ,导入数据import...from

        

         export table student to '/user/zkpk/student';(分区表)

      import table student3 from '/user/zkpk/student';

 一、基本查询

创建emp表(比较规范的SQL语句写法)

create table if not exists emp(

empno int,

ename string,

job string,

mgr int,

hiredate string,

sal double,

comm double,

deptno int

)

row format delimited fields terminated by '\t';

导入数据:

load data local inpath '/home/zkpk/datas/emp.txt' overwrite into table emp;

1、全表查询:select * from student;

2、指定列查询:select id from student;

   注意:查询的列之间用逗号隔开

3、起别名,关键字:as 或者空格

select ename as name,deptno dn from emp;

二、常用函数(计算总行数count、最大值max、最小值min、平均值avg、求和sum)

1、计算emp表总数据的总行数

select count(*) cnt from emp;

2、计算emp表中工资的最大值

select max(sal) max_sal from emp;

3、计算emp表中工资的最小值

select min(sal) min_sal from emp;

4、计算emp表中员工的平均工资

select avg(sal) avg_sal from emp;

5、计算emp表中员工工资的总和

select sum(sal) sum_sal from emp;

6、limit子句:用于返回数据的前几行

返回emp表中数据的前5行

select * from emp limit 5;

7、where语句,用于from后面,过滤掉不符合条件(过滤查询)

查询emp表中工资大于等于3000 的员工的姓名、部门和入职日期

select ename,sal,hiredate,deptno from emp where sal >= 3000;

三、比较运算符

1、查询薪水等于3000的员工的信息

select * from emp where sal = 3000;

2、查询工资在1000到3000之间的员工的信息

select * from emp where sal between 1000 and 3000;

注意:包含1000和3000的数值

3、查询绩效工资不为null的员工信息

select * from emp where comm is not null;

4、查询工资是1500和3000 的员工信息

select * from emp where sal in(1500,3000,5000);

5、查询工资不在2000到3000之间的员工信息(所有信息)(包括2000和3000这两个数)

select * from emp where sal not between 2000 and 3000;

6、like和Rlike

注意:% 代表零个或者多个字符;

      _ 代表一个字符。

         like和Rlike后面的正则表达式用单引号括起。

        

         1)查询工资以2开头的员工信息

         select * from emp where sal like '2%';

        

         2)查询工资包含2的员工信息

         select * from emp where sal Rlike '[2]';

        

         3)查询工资的第二位是2的员工信息

         select * from emp where sal like '_2%';     

练习:

1、查询工资在1500到3000之间的员工编号、名字、入职日期和部门id

select empno,ename,sal,hiredate,deptno from emp where sal between 1500 and 3000;

2、查询工资是800、1500、3000和5000 的员工编号、名字、绩效工资和部门id

select empno,ename,sal,comm,deptno from emp where sal in (800,1500,3000,5000);

3、查询工资不在1500到3000之间的员工编号、名字、工种和部门id(不包含1500和3000这两个数据)

select empno,ename,sal,job,deptno from emp where sal not between 1500 and 3000;

注意:查询条件的列信息一定要显示出来。

四、逻辑运算符(and、or、not)

and表示两个条件并列

or表示两个条件只要其中一个满足即可

not表示否定

1、查询工资大于2000,部门是30的员工信息(两个条件必须同时成立)

select * from emp where sal > 2000 and deptno = 30;

2、查询工资大于2000或者部门是30的员工信息(两个条件成立其一即可)

select * from emp where sal > 2000 or deptno = 30;

3、查询不在部门20 和30 的员工信息

select * from emp where deptno not in (20,30);

五、分组(group by)

注意:1)group by 一般和聚合函数一起使用。

      2)先分组后聚合

1、计算emp表中每个部门的平均工资

select deptno,avg(sal) avg_sal from emp group by deptno; 

2、having语句

注意:1)having针对查询结果的列起作用,where是针对表中的列起作用。

      2)where后面不能跟group by,而having只适用group by后面

        案例:求emp表中部门平均工资大于2000的部门

        分两步:1)求emp表中部门的平均工资

                     select deptno,avg(sal) avg_sal from emp group by deptno;

                    

                2)找出平均工资大于2000的部门

                      select deptno,avg(sal) avg_sal from emp group by deptno having avg_sal > 2000;

排序和join语句

一、join语句:多个表查询

       注意:(1)hive支持是等值join,不支持非等值

                (2)关键字:join ... on(等值条件)

       案例:根据员工表和部门表中的部门ID相等,查询emp表员工编号、员工名称和dept表的部门ID。

                     select e.empno,e.ename,d.deptno from emp e join dept d on e.deptno=d.deptno;

       练习:根据部门表dept和location表的loc相等,查询部门表的部门名称、部门的id和location表中的地名。

1)创建表:

create table location(

loc string,

lname string

)

row format delimited fields terminated by '\t';               

2)导入数据

load data local inpath '/home/zkpk/datas/location.txt' into table location;  

3)联合查询

select d.dname,d.deptno,l.lname from dept d join location l on d.loc=l.loc;               

                           

1、内连接:(1)关键字:join ... on

          (2) 内连接也叫连接,是最早的一种连接。

              (3)只显示满足连接条件的数据,容易丢失数据。

       案例:根据员工表和部门表中的部门ID相等,查询emp表员工编号、员工名称和dept表的部门ID。      

                     select e.empno,e.ename,d.deptno from emp e join dept d on e.deptno=d.deptno;   

              将查询结果导出到本地并格式化。          

insert overwrite local directory '/home/zkpk/datas/export/result'

row format delimited fields terminated by '\t'

select e.empno,e.ename,d.deptno from emp e join dept d on e.deptno=d.deptno;          

2、左外连接:

    (1)关键字:left join ... on

       (2)join左边的表为左表,join右边的表为右表。

       (3)显示左表中的全部数据,右表显示满足条件的数据。

       案例:根据员工表和部门表中的部门ID相等,使用左外连接查询emp表员工编号、员工名称和dept表的部门ID。                         

              select e.empno,e.ename,d.deptno from emp e left join dept d on e.deptno=d.deptno;          

       练习:把dept作为左表,emp为右表           

3、右外连接:

       (1)关键字:right join...on

       (2)显示右表中的所有数据,左表显示满足连接条件的数据

       案例:根据员工表和部门表中的部门ID相等,使用右外连接查询emp表员工编号、员工名称和dept表的部门

              select e.empno,e.ename,d.deptno from emp e right join dept d on e.deptno=d.deptno;         

4、满外连接:

       (1)关键字:full join... on

       (2)显示两个表中的所有数据

       案例:根据员工表和部门表中的部门ID相等,使用右外连接查询emp表员工编号、员工名称和dept表的部门                    

              select e.empno,e.ename,d.deptno from emp e full join dept d on e.deptno=d.deptno;           

5、多表连接:连接n个表,需要n-1个条件

       案例:查询emp表中的empno、enamel和dept表中dname、deptno以及location表中的lname

select e.empno,e.ename,d.dname,d.deptno,l.lname from emp e join dept d

on e.deptno=d.deptno join location l on d.loc=l.loc;(内连接)

练习:查询emp表中的empno、enamel和dept表中dname、deptno以及location表中的lname

要求:第一个连接使用左外连接,第二连接使用右外连接。截图发钉钉群

select e.empno,e.ename,d.dname,d.deptno,l.lname from emp e

left join dept d on e.deptno=d.deptno

right join location l on d.loc=l.loc;

二、排序

1、全局排序:(1)一个MR程序

             (2)order by 跟在from后面

                      (3)默认升序:asc ,降序:desc

                      (4)可以按照别名进行排序

                      (5)可以多个列排序,列名之间用逗号隔开即可

       案例:查询员工信息按员工工资升序排序:select * from emp order by sal asc;

       练习:查询员工信息按员工工资降序排序:select empno,sal from emp order by sal desc;

       案例:查询员工编号、姓名,并按工资的两倍进行降序排序

              select empno,ename,2*sal two_sal from emp order by two_sal desc;

                查询员工编号、姓名,按照部门升序和工资降序进行排序

                select empno,ename,sal,deptno from emp order by deptno desc,sal desc;

2、内部排序:sort by

       (1)每个MapReduce内部有序,全局不一定有序

       (2)适用于多个reduce

       (3)为查看方便输出结果导出到本地

       案例:查询员工编号、姓名,并按工资的降序排序,并将输出结果导出到本地进行格式化;

insert overwrite local directory '/home/zkpk/datas/export/result'

row format delimited fields terminated by '\t'

select empno,ename,sal from emp sort by sal desc;

作业:1、查询员工编号、姓名和部门ID,按照员工编号全局排序并将结果

         导出到hdfs的/user/zkpk/input目录下。

         2、开启4个reduce,查询员工编号、姓名和部门ID,按照员工工资的两倍内部排序,

            将输出结果导出到本地目录/home/zkpk/datas/export

 分桶

1.为社么对数据进行分桶

当对数据进行分区存储,但是没有达到合理的效果时,即某个分区数据过多,则需要对数据进行分桶

分区是针对数据存储目录,分桶是针对数据本身的

2、创建分桶表:关键字:clustered by

Create table if not exists stu_buck(

Id int,

name string

)

Clustered by(id) into 4 buckets   //按id对数据分为4桶

Row formate delimited fields terminated by ‘\t’;

 3.对于分桶表,导入数据之前需要做什么?

Reduce个数与分桶数量进行匹配

Set hive.enforce.bucketing=true;

4.导入数据,通过子查询的方式进行导入数据,关键字:cluster by

Insert into table stu_buck select * from stu cluster by(id);

 5.对分桶数据进行抽样:关键字:tablesample x=2开始  y=总桶数/取桶数

Select * from stu_buck tablesample(bucket x out of y on id);

练习:创建emp表分桶表,分桶字段为deptno,分3桶,

并进行抽样查询,抽取1桶数据,从第2桶开始抽取。

1、创建分桶表

create table if not exists emp_buck(

empno int,

ename string,

job string,

mgr int,

hiredate string,

sal double,

comm double,

deptno int

)

clustered by(deptno) into 3 buckets

row format delimited fields terminated by '\t';

2、设置分桶属性:set hive.enforce.bucketing=true;

3、通过子查询的方式导入数据:

insert into table emp_buck select * from emp cluster by(deptno);

4、抽样查询:抽一桶,从第2桶开始抽样说明x=2,y=总桶数/抽取桶数=3/1=3

select * from emp_buck tablesample(bucket 2 out of 3 on deptno);

 Hived的函数:hive的内置函数和hive的自定义函数

hive的函数:hive的内置函数和hive的自定义函数

一、hive内置函数

1、hive内置函数即hive系统自带的函数,分为四大类:

    1)简单函数(9类)

       2)聚合函数(6类)

       3)集合函数(3类)

       4)特殊函数(3类)

2、hive内置函数的查看和使用

       1)查看hive内置函数:show  functions;(216)

       2)查看具体函数的用法:desc function max;

       3)查看具体函数的详细用法:desc function extended lower;

二、hive的自定义函数

1、hive自定义函数即用户自己定义的函数:分为三大类

       1)UDF:一进一出。比如字母的大小写转换(一对一)

       2)UDAF:聚集函数,多进一出,比如求最大最小值。(多对一)

       3)UDTF:一进多出,比如拆分单词,(一对多)

2、自定义UDF函数(要求熟悉自定义函数的流程)

       案例:大小写字母的转换

       环境准备:

3、自定函数的过程:

       1)自定义的类要继承UDF

       2)实现evaluate函数,业务逻辑代码写入此函数

       3)代码写完保存,打jar包

       4)把jar包导入Linux系统

       5)在hive的命令行窗口创建函数:

              a)添加jar包到class path:add jar /home/zkpk/udf.jar

              b)创建临时函数或者是永久函数

              create [temporary] function +自定义函数名字+as +‘jar包的全类名’;

       6)使用创建的函数。

       7)销毁自定义的临时函数

       drop [temporary] function +函数名字;