✅作者简介:最近接触到大数据方向的程序员,刚入行的小白一枚
🍊作者博客主页:皮皮皮皮皮皮皮卡乒的博客
🍋当前专栏:Hive学习进阶之旅
🍒研究方向:大数据方向,数据汇聚,数据治理
🍎上一篇博文:数据导入和数据导出
文章目录
- 1. 基础查询
- 1.1 WHERE、LIMIT、DISTINCT、BETWEEN、IN的使用
- 1.2 LIKE、GROUP BY、HAVING的使用
- 1.3 内连接&外连接【JOIN...ON ...】
- 2. 排序查询
- 2.1 全局排序(Order By)
- 2.2 单个 Reduce 内部排序(Sort By)
- 2.3 分区(Distribute By)
- 2.4 Cluster By
- 3. 分区表
- 3.1 分区表介绍
- 3.2 创建分区表以及分区表的查询操作
- 3.3 分区修复
1. 基础查询
查询语法
[WITH CommonTableExpression (, CommonTableExpression)*] (Note: Only available starting with Hive 0.13.0)
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 [offset,] rows]
1.1 WHERE、LIMIT、DISTINCT、BETWEEN、IN的使用
WHERE官方文档:
- WHERE
- 功能:使用 WHERE 子句,将不满足条件的行过滤掉
- 操作:WHERE 子句紧随 FROM 子句
LIMIT官方文档:
- LIMIT
- 功能: LIMIT 子句用于限制返回的行数。
- 操作:通常放在查询语句的最后一行。
DISTINCT官方文档:
- DISTINCT
- 功能: 返回不同字段的数据。
- 操作:通常放在查询语句字段前。
- BETWEEN
- 功能: 配合WHERE作为过滤条件使用。
- 操作:通常放在查询语句尾部。
select *
from emp
where sal between 500 and 1000;
- IN
- 功能: 配合WHERE作为过滤条件使用。
- 操作:通常放在查询语句尾部。
select *
from emp
where sal
IN (1500, 5000);
1.2 LIKE、GROUP BY、HAVING的使用
HAVING官方文档:
- Having
- 功能: 放在句末,作为过滤条件,可以跟函数。
- 操作:通常放在查询语句尾部。
- GROUP BY
- 功能:通过字段将表进行分组
- 操作:放在查询末尾,根据需求进行分组查询
eg:计算 emp 表每个部门的平均工资
select t.deptno, avg(t.sal) avg_sal
from emp t
group by t.deptno;
- LIKE
- 功能:进行模糊查询,使用 LIKE 运算选择类似的值。
- 操作:选择条件包含:
- % 代表零个或多个字符(任意个字符)。
- _ 代表一个字符。
eg1:查找名字以 A 开头的员工信息
select *
from emp
where ename LIKE 'A%';
eg2:查找名字中第二个字母为 A 的员工信息
select *
from emp
where ename LIKE '_A%';
eg3:查找名字中带有 A 的员工信息
select *
from emp
where ename RLIKE '[A]';
1.3 内连接&外连接【JOIN…ON …】
- 内连接
- 功能:只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。
- 外连接神图
- 左外连接:公共部分+左表独有
- 右外连接:公共部分+右表独有
- 满外连接:两个表所有数据
- 左外连接除公共部分:过滤时使用:where B.field IS NULL
- 右外连接除公共部分:过滤时使用:where A.field IS NULL
- 两个表独有部分::过滤时使用:full join + where A.field IS NULL and B.field IS NULL
说明:
以下查询是基于两张表实现的,一张是员工表:员工姓名,员工编号,员工部门编号;一张是部门表:部门编号,部门名称,使用部门编号来连接两张表
分别依次实现:左外,右外、左外除去公共部分,右外除去公共部分、满外连接、两张表除公共部分
select e.empno, e.ename, d.deptno
from emp e
left join dept d
on e.deptno = d.deptno;
select e.empno, e.ename, d.deptno
from emp e
right join dept d
on e.deptno = d.deptno;
select e.empno,e.ename,e.deptno,d.dname
from emp e
left join dept d
on e.deptno = d.deptno
where d.deptno is null;
select e.empno,e.ename,e.deptno,d.dname
from emp e
right join dept d
on e.deptno = d.deptno
where d.deptno is null;
select e.empno,e.ename,nvl(e.deptno,d.deptno),d.dname
from emp e
full join dept d
on e.deptno = d.deptno;
select e.empno,e.ename,e.deptno,d.deptno,d.dname
from emp e
full join dept d
on e.deptno = d.deptno
where e.deptno is null or d.deptno is null;
2. 排序查询
2.1 全局排序(Order By)
Order By:全局排序,只有一个 Reducer
- 针对一个字段对全表进行排序
- ASC (ascend) : 升序 (默认)
- DESC (descend) : 降序
2.2 单个 Reduce 内部排序(Sort By)
Sort By:对于大规模的数据集 order by 的效率非常低。在很多情况下,并不需要全局排序,此时可以使用 sort by。
Sort by 为每个 reducer 产生一个排序文件。每个 Reducer 内部进行排序,对全局结果集 来说不是排序。通常结合Order By使用
2.3 分区(Distribute By)
Distribute By: 在有些情况下,我们需要控制某个特定行应该到哪个 reducer,通常是为 了进行后续的聚集操作。 distribute by 子句可以做这件事。distribute by 类似 MR 中 partition (自定义分区) ,进行分区,结合 sort by 使用。
对于 distribute by 进行测试,一定要分配多 reduce 进行处理, 否则无法看到 distribute by 的效果。
对每个部门的员工,按照部门编号进行排序展示:
select *
from emp
distribute by deptno
sort by empno desc;
2.4 Cluster By
3. 分区表
3.1 分区表介绍
分区表实际上就是对应一个 HDFS 文件系统上的独立的文件夹, 该文件夹下是该分区所 有的数据文件。Hive 中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据 集。在查询时通过 WHERE 子句中的表达式选择查询所需要的指定的分区,这样的查询效率 会提高很多。
3.2 创建分区表以及分区表的查询操作
创建分区表:
create table dept_partition(
deptno int, dname string, loc string
)
partitioned by (day string)
row format delimited fields terminated by '\t';
创建二级分区(将分区在进行细分):
create table dept_partition2(
deptno int, dname string, loc string )
partitioned by (day string, hour string)
row format delimited fields terminated by '\t';
分区字段在:partitioned by后面出现
区分区表加载数据:
将数据添加到三个分区
load data local inpath
'/opt/module/hive/datas/dept_20200401.log'
into table dept_partition
partition(day='20200401');
load data local inpath
'/opt/module/hive/datas/dept_20200402.log'
into table dept_partition
partition(day='20200402');
load data local inpath
'/opt/module/hive/datas/dept_20200403.log'
into table dept_partition
partition(day='20200403');
查询分区数据:
select *
from dept_partition
where day='20200401';
分区操作:
3.3 分区修复
分区修复的原因:
把数据直接上传到分区目录上,让分区表和数据没有产生关联,也就是说没有元数据,对应表和实际存放数据的映射
- 方式一:
- 上传数据,并且创建表完成
- 执行修复命令:msck repair table dept_partition2;
- 方式二:
- 上传数据后添加分区
- 手动添加分区:alter table dept_partition2 add partition(day=‘201709’,hour=‘14’);
- 方式三:
- 创建文件夹
- 使用load命令加载数据到HDFS