大数据之-hive

1 hive环境搭建

2hive 安装

2.1 hive交互命令

1) “-e”不进入 hive 的交互窗口执行 sql 语句
[root@hadoop102 hive]# bin/hive -e “select * from test”
2) “-f”执行脚本中 sql 语句
bin/hive -f /opt/module/hive/datas/hivef.sql
主要运用写脚本时候使用的。

3 Hive数据类型

3.1 基本数据类型

大数据之-hive_第1张图片
对于 Hive 的 String 类型相当于数据库的 varchar 类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储 2GB 的字符数。

3.2 集合数据类型

大数据之-hive_第2张图片

  1. Hive 有三种复杂数据类型 ARRAY、MAP 和 STRUCT。
  2. ARRAY 和 MAP 与 Java 中的 Array 和 Map 类似
  3. STRUCT 与 java中的对象,复杂数据类型允许任意层次的嵌套。

3.3 数据操作

3.3.1创建表:

大数据之-hive_第3张图片

3.3.2 数据put到hadoop上

把对应的数据put到hadoop对应hive目录中
在这里插入图片描述

3.3.3 Array访问数据

select array类型的字段[index] from 表名;
Array类型的数据支持下标访问
大数据之-hive_第4张图片

3.3.4 map数据结构访问

select children[“xiao song”] from test6;
大数据之-hive_第5张图片

3.3.5 结构体(Bean)访问

hive (default)> select address.street from test6;
大数据之-hive_第6张图片

3.4 类型转换

hive数据类型自动转换只能向大的类型转换。
1) 隐式类型转换规则如下
(1) 任何整数类型都可以隐式地转换为一个范围更广的类型,如 TINYINT 可以转换成
INT,INT 可以转换成 BIGINT。
(2) 所有整数类型、FLOAT 和 STRING 类型都可以隐式地转换成 DOUBLE。
(3) TINYINT、SMALLINT、INT 都可以转换为 FLOAT。
(4) BOOLEAN 类型不可以转换为任何其它的类型。
2) 可以使用 CAST 操作显示进行数据类型转换例如 CAST(‘1’ AS INT)将把字符串’1’ 转换成整数 1;如果强制类型转换失败,如执行
CAST(‘X’ AS INT),表达式返回空值 NULL。

4 DDL数据定义

4.1 创建数据库

CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment] //注释
[LOCATION hdfs_path] //存放路径
[WITH DBPROPERTIES (property_name=property_value, …)];//额外的参数信息

1) 创建一个数据库,数据库在 HDFS 上的默认存储路径是/user/hive/warehouse/*.db。
hive (default)> create database db_hive;
2) 避免要创建的数据库已经存在错误,增加 if not exists 判断。(标准写法)
hive (default)> create database db_hive; FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Database db_hive already exists hive (default)> create database if not exists db_hive;
3) 创建一个数据库,指定数据库在 HDFS 上存放的位置
hive (default)> create database db_hive2 location ‘/db_hive2.db’;

4.2 查询数据库

1) 显示数据库
hive> show databases;
2) 过滤显示查询的数据库
hive> show databases like ‘db_hive*’; OK db_hive db_hive_1
3) 切换库
use 库名;
4)查询数据详情
desc database 库名

4.3 修改数据库

用户可以使用 ALTER DATABASE 命令为某个数据库的 DBPROPERTIES 设置键-值对属性值,
来描述这个数据库的属性信息。
alter database db_hive set dbproperties(‘createtime’=‘20170830’);

4.4 删除数据库

1) 删除空数据库
hive>drop database db_hive2;
2) 如果删除的数据库不存在,最好采用 if exists 判断数据库是否存在
hive> drop database db_hive;
FAILED: SemanticException [Error 10072]: Database does not exist: db_hive hive> drop database if exists db_hive2;
3) 如果数据库不为空,可以采用 cascade 命令,强制删除
hive> drop database db_hive;
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. InvalidOperationException(message:Database db_hive is not empty. One or more tables exist.)
hive> drop database db_hive cascade;

4.5 创建表

建表语句:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
[(col_name data_type [COMMENT col_comment], ...)] 
[COMMENT table_comment] 
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) 
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 
[ROW FORMAT row_format] 
[STORED AS file_format] 
[LOCATION hdfs_path] 
[TBLPROPERTIES (property_name=property_value, ...)] 
[AS select_statement] 

[EXTERNAL] :外部的---->Hive表中会有内外之分
[PARTITIONED BY:分区表
[CLUSTERED BY:分桶表
[SORTED BY (col_name [ASC|DESC], …)] INTO num_buckets BUCKETS] :分桶表,指定分桶个数
[ROW FORMAT row_format] 定义行的格式
[STORED AS file_format] :指定文件格式
[LOCATION hdfs_path] :指定表的位置信息
[TBLPROPERTIES (property_name=property_value, …)] :额外属性
[AS select_statement] :后跟查询语句,根据查询结果创建表

4.5.1 管理表(内部表)

应用场景比较少–不安全。
1) 理论默认创建的表都是所谓的管理表,有时也被称为内部表。因为这种表,Hive 会(或多或少地)控制着数据的生命周期。
Hive 默认情况下会将这些表的数据存储在由配置项 hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。
当我们删除一个管理表时,Hive 也会删除这个表中数据
管理表不适合和其他工具共享数据。
内部表删除的时候元数据与数据都会删除。

4.5.2 外部表

1) 理论
因为表是外部表,所以 Hive 并非认为其完全拥有这份数据。删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉。
2) 管理表和外部表的使用场景每天将收集到的网站日志定期流入 HDFS 文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过 SELECT+INSERT 进入内部表。

4.5.3 管理表与外部表相互转换

(2) 修改内部表 student2 为外部表
alter table 表名 set tblproperties(‘EXTERNAL’=‘TRUE’);
大数据之-hive_第7张图片
注意:(‘EXTERNAL’=‘TRUE’)和(‘EXTERNAL’=‘FALSE’)为固定写法,区分大小写!
desc formatted student2; 查询表结构

4.5.4 创建表时指定分隔符

问题:假如创建一张表不指定分隔符,导出数据默认会在数据之间添加分割符,不利于其他程序使用。
案例:
1、创建一张表
指定分隔符
row format delimited fields terminated by “,”;
大数据之-hive_第8张图片
2、向表中插入数据
3、查询数据,数据中间有,分割
在这里插入图片描述
结论:如果我们不按逗号分割,hive将不会识别

4.6 修改表

4.6.1 重命名表明

1) 语法
ALTER TABLE table_name RENAME TO new_table_name
2) 实操案例
hive (default)> alter table dept_partition2 rename to dept_partition3;
注意:修改的表名必须不存在

4.6.2 增/修/替换列信息

1) 语法
(1) 更新列
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
hive (default)> alter table test1 change 旧列名 新列名 string(新列名数据类型); 注意字段的数据类型不能向下转
(2) 增加和替换列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], …)
注:ADD 是代表新增一字段,字段位置在所有列后面(partition 列前),
REPLACE 则是表示替换表中所有字段。
hive (default)> alter table test1 add columns (name string);
(3) 替换列
hive (default)> alter table dept replace columns(deptno string, dname string, loc string);

5 DML数据操作

5.1 数据导入

1) 语法
hive> load data [local] inpath ‘数据的path’ [overwrite] into table student [partition (partcol1=val1,…)];
(1) load data:表示加载数据
(2) local:表示从本地加载数据到 hive 表;否则从 HDFS 加载数据到 hive 表
(3) inpath:表示加载数据的路径
(4) overwrite:表示覆盖表中已有数据,否则表示追加
(5) into table:表示加载到哪张表
(6) student:表示具体的表
(7) partition:表示上传到指定分区

5.2 案例

5.2.1 本地加载文件(重点)

1、创建表

create table student(id int,name string) row format delimited fields terminated by '\t';

2、在本地新建一个文件
2、在hive命令行中导入数据

load data local inpath "./student.txt" into table student;

实际上是把数据传到HDFS上
大数据之-hive_第9张图片insert 会走mr 会修改元数据
**put:**和hive没有关系,put上去的数据count查不到数据,
**load:**会修改元数据的numFiles 不会修改元数据中的numRows

5.2.2 HDFS数据导入

加载数据于文件大小没有关系。
1、将文件put到HDFS上
2、HDFS文件导入

load data inpath '/student.txt' into table student1;

相当于剪切操作,其实修改的是nameNode的元数据。实际目录没变。

5.2.3 通过查询语句向表中插入数据(Insert)重点

通过在另外一张表中查询数据然后导入另外一张表:
1) 创建一张表
hive (default)> create table student_par(id int, name string) row format delimited fields terminated by ‘\t’;
2) 基本插入数据
hive (default)> insert into table student_par values(1,‘wangwu’),(2,‘zhaoliu’);
3) 基本模式插入(根据单张表查询结果)
hive (default)> insert overwrite table student_par select id, name from student where month=‘201709’;
insert into:以追加数据的方式插入到表或分区,原有数据不会删除
insert overwrite:会覆盖表中已存在的数据注意可以修改表中的字段。

5.2.4 查询语句中创建表并加载数据(As Select)

根据查询结果创建表(查询的结果会添加到新创建的表中)
create table if not exists student3 as select id, name from student;

5.2.5 创建表时通过 Location 指定加载数据路径

1) 上传数据到 hdfs 上
hive (default)> dfs -mkdir /student;
hive (default)> dfs -put /opt/module/datas/student.txt /student;
2) 创建表,并指定在 hdfs 上的位置
hive (default)> create external table if not exists student5( id int, name string
) row format delimited fields terminated by ‘\t’ location '/student;
3) 查询数据
hive (default)> select * from student5;
一般我们直接在

5.3 数据导出

5.3.1 Insert导出

1) 将查询的结果导出到本地
hive (default)> insert overwrite local directory
‘/opt/module/hive/data/export/student’ select * from student;
2) 将查询的结果格式化导出到本地
hive(default)>insert overwrite local directory ‘/opt/module/hive/data/export/student1’ ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’ select * from student;
3) 将查询的结果导出到 HDFS 上(没有 local)
hive (default)> insert overwrite directory ‘/user/atguigu/student2’ ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’ select * from student;

5.3.2 Hadoop命令导出到本地

方式一:
Hadoop命令:hadoop fs -get /user/hive/warehouse/student/student.txt /home/lianglin/module/hive/ss.txt
方式二:重定向输出
bin/hive -e ‘select * from default.student;’ > /opt/module/hive/data/export/student4.txt;
方式三:hive客户端
dfs -get /user/hive/warehouse/student/student.txt /opt/module/data/export/student3.txt;

5.3.3 Export导出到HDFS上

hive (default)> export table student to “/stuendt1”;
export 和 import 主要用于两个 Hadoop 平台集群之间 Hive 表迁移。
大数据之-hive_第10张图片
注意:先用 export 导出后,再将数据导入。
hive (default)> import table student2 from ‘/user/hive/warehouse/export/student’;
可以再用import导入到Hive中
Sqoop:数据量小了之后分析完之后的结果导入到mysql

5.3.4清空表中的数据

注意:Truncate 只能删除管理表,不能删除外部表中数据
hive (default)> truncate table student;

6 查询语句

查询语句语法:
SELECT [ALL | DISTINCT] select_expr, select_expr, …
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ORDER BY col_list]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT number]

6.1 准备数据

员工表
7499,ALLEN,SALESMAN,7698,1981-2-20,1600.00,300.00,30
7521,WARD,SALESMAN,7698,1981-2-22,1250.00,500.00,30
7566,JONES,MANAGER,7839,1981-4-2,2975.00,,20
7654,MARTIN,SALESMAN,7698,1981-9-28,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,1981-5-1,2850.00,,30
7782,CLARK,MANAGER,7839,1981-6-9,2450.00,,10
7788,SCOTT,ANALYST,7566,1987-4-19,3000.00,,20
7839,KING,PRESIDENT,,1981-11-17,5000.00,,10
7844,TURNER,SALESMAN,7698,1981-9-8,1500.00,0.00,30
7876,ADAMS,CLERK,7788,1987-5-23,1100.00,,20
7900,JAMES,CLERK,7698,1981-12-3,950.00,,30
7902,FORD,ANALYST,7566,1981-12-3,3000.00,,20
7934,MILLER,CLERK,7782,1982-1-23,1300.00,,10

部门表;
10      ACCOUNTING      1700
20      RESEARCH        1800
30      SALES   1900
40      OPERATIONS      1700

建表语句:
(1) 创建部门表
create table if not exists dept( deptno int, dname string, loc int )
row format delimited fields terminated by ‘\t’;
(2) 创建员工表
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 ‘,’;
(3) 导入数据
load data local inpath ‘/opt/module/datas/dept.txt’ into table dept;
load data local inpath ‘/opt/module/datas/emp.txt’ into table emp;

6.1 Hsql查询练习

(1) SQL 语言大小写不敏感。
(2) SQL 可以写在一行或者多行
(3)关键字不能被缩写也不能分行
(4)各子句一般要分行写
(5)使用缩进提高语句的可读性

select empno,ename from emp;
select empno,ename e from emp;

6.2 算数运算符

大数据之-hive_第11张图片

6.2 常用函数

1) 求总行数(count)
hive (default)> select count(*) cnt from emp;
2) 求工资的最大值(max)
hive (default)> select max(sal) max_sal from emp;
3) 求工资的最小值(min)
hive (default)> select min(sal) min_sal from emp;
4) 求工资的总和(sum)
hive (default)> select sum(sal) sum_sal from emp;
5) 求工资的平均值(avg)
hive (default)> select avg(sal) avg_sal from emp;
在这里插入图片描述

6.3 Limit 语句

典型的查询会返回多行数据。LIMIT 子句用于限制返回的行数
select * from emp order by sal limit 5;
在这里插入图片描述

6.4 Where语句

1) 使用 WHERE 子句,将不满足条件的行过滤掉
2) WHERE 子句紧随 FROM 子句
大数据之-hive_第12张图片

6.5 比较运算符

1) 下面表中描述了谓词操作符,这些操作符同样可以用于 JOIN…ON 和 HAVING 语句中。
大数据之-hive_第13张图片
(1) 查询出薪水等于 5000 的所有员工
hive (default)> select * from emp where sal =5000;
(2) 查询工资在 500 到 1000 的员工信息
hive (default)> select * from emp where sal between 500 and 1000;
(3) 查询 comm 为空的所有员工信息
hive (default)> select * from emp where comm is null;
(4) 查询工资是 1500 或 5000 的员工信息
hive (default)> select * from emp where sal IN (1500, 5000);

6.6 Like 和RLike

1)使用 LIKE 运算选择类似的值 2)选择条件可以包含字符或数字:
% 代表零个或多个字符(任意个字符)。
_ 代表一个字符。

3) RLIKE 子句
RLIKE 子句是 Hive 中这个功能的一个扩展,其可以通过 Java 的正则表达式这个更强大的语言来指定匹配条件。
4) 案例实操
(1) 查找名字以 A 开头的员工信息
hive (default)> select * from emp where ename LIKE ‘A%’;
(2) 查找名字中第二个字母为 A 的员工信息
hive (default)> select * from emp where ename LIKE ‘_A%’;
(3) 查找名字中带有 A 的员工信息
hive (default)> select * from emp where ename RLIKE ‘[A]’;

6.7 逻辑运算符

(1) 查询薪水大于 1000,部门是 30
hive (default)> select * from emp where sal>1000 and deptno=30;
(2) 查询薪水大于 1000,或者部门是 30
hive (default)> select * from emp where sal>1000 or deptno=30;
(3) 查询除了 20 部门和 30 部门以外的员工信息
hive (default)> select * from emp where deptno not IN(30, 20);

6.8 group by

GROUP BY 语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作。
查询平均工资大于2000的部门

#嵌套子查询
select deptno,avg_sal from (select deptno,avg(sal) avg_sal from emp group by deptno) where avg_sal > 2000;
#对于字段使用函数的列使用条件筛查必须使用having
select deptno,avg(sal) avg_sal from emp group by deptno having avg_sal > 2000;

6.9 Join语句

Join用于连接多张表
e.empno:e.定位提高效率

#根据员工表和部门表中的部门编号相等,查询员工编号、员工名称和部门名称;
select e.empno,e.ename,t.dname from emp e join dept t on e.deptno = t.deptno;

6.10 表别名

(1) 使用别名可以简化查询。
(2) 使用表名前缀可以提高执行效率。

6.11 内连接 join on

得到两张表都有的数据

6.12 左外连接 left join on

左外连接:JOIN 操作符左边表中符合 WHERE 子句的所有记录将会被返回。(左边的数据都要没有的补null)

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

6.13 右外连接 right join on

右外连接:JOIN 操作符右边表中符合 WHERE 子句的所有记录将会被返回。 (以右边表为主)

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

6.14 满外连接 full join on

满外连接:将会返回所有表中符合 WHERE 语句条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用 NULL 值替代。

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

6.15 左表独有的数据

查询员工信息,所处的部门信息非null
select e.empno,e.ename,p.dname,e.deptno from emp e left join dept p on e.deptno = p.deptno where p.deptno is null;

6.16 有表独有的数据

查询部门中不存在任何员工的部门信息

select  p.deptno,p.dname from emp e right join dept p on e.deptno = p.deptno where e.deptno is null;

6.17 查询两张表特有的信息

select e.empno,e.ename,p.dname,e.deptno from emp e full join dept p on e.deptno = p.deptno where e.deptno is null or p.deptno is null;

6.18 多表连接

大多数情况下,Hive 会对每对 JOIN 连接对象启动一个 MapReduce 任务。本例中会首先启动一个 MapReduce job 对表 e 和表 d 进行连接操作,然后会再启动一个 MapReduce job 将第一个 MapReduce job 的输出和表 l;进行连接操作。
注意:为什么不是表 d 和表 l 先进行连接操作呢?这是因为 Hive 总是按照从左到右的顺序执行的。
优化:当对 3 个或者更多表进行 join 连接时,如果每个 on 子句都使用相同的连接键的
话,那么只会产生一个 MapReduce job。
多表join 直接在后面join on

select e.ename,p.dname,l.loc_name from emp e join dept p on e.deptno = d.deptno join location l on p.loc = l.loc;

大数据之-hive_第14张图片

6.19 笛卡尔积

1) 笛卡尔集会在下面条件下产生
(1) 省略连接条件
(2) 连接条件无效
(3) 所有表中的所有行互相连接

6.20 排序

6.20.1 全局排序

Order By:全局排序,只有一个 Reducer
1)使用 ORDER BY 子句排序
ASC(ascend): 升序(默认) DESC(descend): 降序 2)ORDER BY 子句在 SELECT 语句的结尾
按工资排序:

select ename,sal from emp order by sal;

6.20.2 每个Reduce内部排序(Sort By)

区内有序
Sort By:对于大规模的数据集 order by 的效率非常低。在很多情况下,并不需要全局排序,此时可以使用 sort by。
Sort by 为每个 reducer 产生一个排序文件。每个 Reducer 内部进行排序,对全局结果集来说不是排序。
1) 设置 reduce 个数
hive (default)> set mapreduce.job.reduces=3;
2) 查看设置 reduce 个数
hive (default)> set mapreduce.job.reduces;

6.20.3 分区(Distribute By)

Distribute By: 在有些情况下,我们需要控制某个特定行应该到哪个 reducer,通常是为了进行后续的聚集操作。distribute by 子句可以做这件事。distribute by 类似 MR 中 partition (自定义分区),进行分区,结合 sort by 使用。
对于 distribute by 进行测试,一定要分配多 reduce 进行处理,否则无法看到 distribute by 的效果。

select ename,deptno from emp distribute by deptno sort by deptno;

➢ distribute by 的分区规则是根据分区字段的 hash 码与 reduce 的个数进行模除后,余数相同的分到一个区。
➢ Hive 要求 DISTRIBUTE BY 语句要写在 SORT BY 语句之前。

6.20.4 Cluster by

当 distribute by 和 sorts by 字段相同时,可以使用 cluster by 方式。
cluster by 除了具有 distribute by 的功能外还兼具 sort by 的功能。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC。
(1)以下两种写法等价
hive (default)> select * from emp cluster by deptno;
hive (default)> select * from emp distribute by deptno sort by deptno;
注意:按照部门编号分区,不一定就是固定死的数值,可以是 20 号和 30 号部门分到一个分区里面去。

7 分区表和分桶表

7.1 分区表

提高效率避免全表扫描,where条件中有分区字段。
分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive 中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过 WHERE 子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。

1、创建分区表

create table dept_partition( deptno int, dname string, loc string 
) 
partitioned by (day string) 
row format delimited fields terminated by ','; 

数据加载
hive (default)> load data local inpath
‘/opt/module/hive/datas/dept_20200401.log’ into table dept_partition partition(day=‘20200401’);
hive (default)> load data local inpath
‘/opt/module/hive/datas/dept_20200402.log’ into table dept_partition partition(day=‘20200402’);
hive (default)> load data local inpath
‘/opt/module/hive/datas/dept_20200403.log’ into table dept_partition partition(day=‘20200403’);
注意:分区表加载数据时,必须指定分区
4) 查询分区表中数据单分区查询
hive (default)> select * from dept_partition where day=‘20200401’;
多分区联合查询
hive (default)> select * from dept_partition where day=‘20200401’ union select * from dept_partition where day=‘20200402’ union select * from dept_partition where day=‘20200403’; hive (default)> select * from dept_partition where day=‘20200401’ or day=‘20200402’ or day=‘20200403’;
5) 增加分区创建单个分区
hive (default)> alter table dept_partition add partition(day=‘20200404’);
同时创建多个分区
hive (default)> alter table dept_partition add partition(day=‘20200405’) partition(day=‘20200406’);
6) 删除分区删除单个分区
hive (default)> alter table dept_partition drop partition
(day=‘20200406’);
同时删除多个分区
hive (default)> alter table dept_partition drop partition
(day=‘20200404’), partition(day=‘20200405’);
7) 查看分区表有多少分区
hive> show partitions dept_partition;
8) 查看分区表结构
hive> desc formatted dept_partition;

7.2 二级分区

如何一天的日志数据量也很大,如何再将数据拆分? 按小时分区
1、创建表

hive (default)> create table dept_par1(deptno int,dname string,loc string)
              > partitioned by (day string,hour string) row format delimited fields terminated by ",";

2、加载数据
day=“2021-9-23”,hour=“15” 按小时分区
load data local inpath “/home/lianglin/module/hive/data/dept1.txt” into table dept_par1 partition**(day=“2021-9-23”,hour=“15”);**
3、查询数据
select * from dept_par1 where day=“2021-9-23” and hour=“15”;
在这里插入图片描述
3) 把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
方式一:hive> msck repair table dept_partition2;
方式二:上传数据后添加分区上传数据
执行添加分区
hive (default)> alter table dept_partition2 add partition(day=‘201709’,hour=‘14’);
方式三:创建文件夹后 load 数据到分区

7.3 动态分区调整

关系型数据库中,对分区表 Insert 数据时候,数据库自动会根据分区字段的值,将数据
插入到相应的分区中,Hive 中也提供了类似的机制,即动态分区(Dynamic Partition),只不过,使用 Hive 的动态分区,需要进行相应的配置。
默认最后一个字段作为分区
1) 开启动态分区参数设置
(1) 开启动态分区功能(默认 true,开启)
hive.exec.dynamic.partition=true
(2) 设置为非严格模式(动态分区的模式,默认 strict,表示必须指定至少一个分区为静态分区,nonstrict 模式表示允许所有的分区字段都可以使用动态分区。)
hive.exec.dynamic.partition.mode=nonstrict
(3) 在所有执行 MR 的节点上,最大一共可以创建多少个动态分区。默认 1000
hive.exec.max.dynamic.partitions=1000
(4) 在每个执行 MR 的节点上,最大可以创建多少个动态分区。该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即 day 字段有 365 个值,那么该参数就需要设置成大于 365,如果使用默认值 100,则会报错。
hive.exec.max.dynamic.partitions.pernode=100
(5) 整个 MR Job 中,最大可以创建多少个 HDFS 文件。默认 100000
hive.exec.max.created.files=100000
(6) 当有空分区生成时,是否抛出异常。一般不需要设置。默认 false
hive.error.on.empty.partition=false

7.4 分桶表

分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区。对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分。分桶是将数据集分解成更容易管理的若干部分的另一个技术。分区针对的是数据的存储路径;分桶针对的是数据文件。
在数据量极大的时候使用,抽样查询
(2) 创建分桶表
create table stu_buck(id int, name string) clustered by(id) into 4 buckets
row format delimited fields terminated by ‘\t’;

7.5 抽样查询

对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive 可以通过对表进行抽样来满足这个需求。
语法: TABLESAMPLE(BUCKET x OUT OF y)
查询表 stu_buck 中的数据。
hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id);
注意:x 的值必须小于等于 y 的值,否则
FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck

8 函数

8.1 系统内置函数

1) 查看系统自带的函数
hive> show functions;
2) 显示自带的函数的用法
hive> desc function upper;
3) 详细显示自带的函数的用法
hive> desc function extended upper;

8.2 常用内置函数

8.2.1 NVL空字段赋值

1) 函数说明
NVL:给值为 NULL 的数据赋值,它的格式是 NVL( value,default_value)。它的功能是如果 value 为 NULL,则 NVL 函数返回 default_value 的值,否则返回 value 的值,如果两个参数都为 NULL ,则返回 NULL。
练习:如果员工的 comm 为 NULL,则用-1 代替

select comm,nvl(comm,-1) from emp;

大数据之-hive_第15张图片

8.2.2 CASE WHEN THEN ELSE END

需求:求每个部门男女有多少人
大数据之-hive_第16张图片
第一种写法:

select
	dept_id,
	sum(case sex when "男" then 1 else 0 end) maleCount,
	sum(case sex when "女" then 1 else 0 end) femaleCount
from 
	emp_sex
group by 
	dept_id;

第二种写法,当只有两个分支的时候

select dept_id,sum(if(sex="男",1,0)) maleCount,sum(if(sex = "女",1,0)) femaleCount from emp_sex group by dept_id;

8.2.3 行转列

多列合并
1) 相关函数说明
1、CONCAT(string A/col, string B/col…):返回输入字符串连接后的结果,支持任意个输入字符串;
2、CONCAT_WS(separator, str1, str2,…):它是一个特殊形式的 CONCAT()。第一个参数剩余参
数间的分隔符。分隔符可以是与剩余参数一样的字符串。如果分隔符是 NULL,返回值也将为 NULL。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。分隔符将被加到被连接的字符串之间;
注意: CONCAT_WS must be "string or array
3、COLLECT_SET(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生 Array 类型字段。 类似于聚合函数;collect_list不去重
1、练习

name,constellation,blood_type
孙悟空,白羊座,A
大海,射手座,A
小宋,白羊座,B
猪八戒,白羊座,A
凤姐,射手座,A
小五,白羊座,B

建表语句

create table person_info( name string,  constellation string,  blood_type string)  row format delimited fields terminated by ",";

第一步:把姓名与血型拼接在一起

select name,concat(constellation,",",blood_type) con_blood from person_info;t1

第二步:使用collect_set把名字聚合成集合

select con_blood,collect_set(name) arr_list 
from 
(select name,concat(constellation,",",blood_type) con_blood from person_info) t1 
group by con_blood;

在这里插入图片描述

第三步:使用concat_ws将名字使用|拼接起来,

select con_blood,concat_ws("|",collect_set(name)) name_arr 
from
(select name,concat(constellation,",",blood_type) con_blood from person_info)t1
group by con_blood;

在这里插入图片描述

8.2.3 列转行

一行变多行
1) 函数说明
EXPLODE(col):将 hive 一列中复杂的 Array 或者 Map 结构拆分成多行。
LATERAL VIEW 用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:用于和 split, explode 等 UDTF 一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。

数据

movie|category 
《疑犯追踪》|悬疑,动作,科幻,剧情 
《Lie to me》|悬疑,警匪,动作,心理,剧情 
《战狼 2》|战争,动作,灾难 

建表语句

create table movie_info(movie string,category string) row format delimited fields terminated by "|";

1、使用split将字段分割–字符串转换为数组
大数据之-hive_第17张图片2、
2、explod 将array转成列
lateral view 加侧写表,如果炸裂出来的列于原表种的字段有关联。

select movie,categora_name from movie_info lateral view explode(split(category,",")) move_info_tmp as categora_name;

8.2.4 窗口函数(开窗函数)

partition by 限制窗口大小 order by 排序
1)相关函数说明
OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
CURRENT ROW:当前行 n PRECEDING:往前 n 行数据 n FOLLOWING:往后 n 行数据
UNBOUNDED:起点,
UNBOUNDED PRECEDING 表示从前面的起点,
UNBOUNDED FOLLOWING 表示到后面的终点
LAG(col,n,default_val):往前第 n 行数据
LEAD(col,n, default_val):往后第 n 行数据

jack,2017-01-01,10 
tony,2017-01-02,15 
jack,2017-02-03,23 
tony,2017-01-04,29 
jack,2017-01-05,46 
jack,2017-04-06,42 
tony,2017-01-07,50 
jack,2017-01-08,55 
mart,2017-04-08,62 
mart,2017-04-09,68 
neil,2017-05-10,12 
mart,2017-04-11,75 
neil,2017-06-12,80 
mart,2017-04-13,94
create table business( name string, orderdate string, 
cost int 
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

(1) 查询在 2017 年 4 月份购买过的顾客及总人数

select name,count(1) over() from business where substring(orderdate,0,7) = "2017-04" group by name;

(1) 查询顾客购买明细,消费总额
通过窗口函数,通过名字开窗,计算窗口内部的数量

select name,orderdate,cost,sum(cost) over(partition by name) from business;

大数据之-hive_第18张图片

(2) 查询顾客的购买明细及月购买总额
over(partition by name,month(orderdate)) 提供更加细粒度的分组。

select name,orderdate,cost,sum(cost) over(partition by name,month(orderdate)) from business;

大数据之-hive_第19张图片
(3) 将每个顾客的 cost 按照日期进行累加
排序的时候如果相同数据,则开的窗口一样大

select name,orderdate,cost,sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and CURRENT ROW) from business;
等价于
select name,orderdate,cost,sum(cost) over(partition by name order by orderdate) from business;

大数据之-hive_第20张图片

(4) 查看顾客上次的购买时间

select name,orderdate,lag(orderdate,1) over(partition by name order by orderdate) from business;
select name,orderdate,lag(orderdate,1,"2017-01-01") over(partition by name order by orderdate) from business;

使用场景:页面的单跳转化率
大数据之-hive_第21张图片

(5) 查询前 20%时间的订单信息
NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对于每一行,NTILE 返回此行所属的组的编号。注意:n 必须为 int 类型。

select name,orderdate,cost,ntile(5) over(order by orderdate) group_id from business t1;
select name,orderdate,cost from (select name,orderdate,cost,ntile(5) over(order by orderdate) group_id from business)t1 where group_id = 1;

8.2.5 Rank()排序

1) 函数说明
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算

name,subject,score
孙悟空,语文,87
孙悟空,数学,95
孙悟空,英语,68
大海,语文,94
大海,数学,56
大海,英语,84
宋宋,语文,64
宋宋,数学,86
宋宋,英语,84
婷婷,语文,65
婷婷,数学,85
婷婷,英语,78
create table score( name string, subject string,  score int)  row format delimited fields terminated by ","; 

练习

select *,rank() over(order by score) from score;

大数据之-hive_第22张图片

select *,dense_rank() over(order by score) from score;

大数据之-hive_第23张图片

select *,row_number() over(order by score) from score;

大数据之-hive_第24张图片
按学科排名并取每个学科的前三名 --分组topN问题

select name,subject,score from (select *,rank() over(partition by subject order by score desc) rk from score
)t1 where rk <= 3;

大数据之-hive_第25张图片

你可能感兴趣的:(大数据,hive,大数据)