【Hive

1、基础语法

查询语句语法

SELECT [ALL | DISTINCT] select_expr, select_expr, ...
  FROM table_reference       -- 从什么表查
  [WHERE where_condition]   -- 过滤
  [GROUP BY col_list]        -- 分组查询
   [HAVING col_list]          -- 分组后过滤
  [ORDER BY col_list]        -- 排序
  [CLUSTER BY col_list
    | [DISTRIBUTE BY col_list] [SORT BY col_list]
  ]
 [LIMIT number]                -- 限制输出的行数
  • Having是对分组之后的每组数据进行查询。

2、基本查询Select…From

数据准备

0原始数据

①在/home/wenxin/module/hive/datas/路径上创建dept.txt文件并赋值如下内容
部门编号 部门名称 部门位置id

10	行政部	1700
20	财务部	1800
30	教学部	1900
40	销售部	1700

②在/opt/module/hive/datas/路径上创建emp.txt文件并赋值如下内容
员工编号 姓名 岗位 薪资 部门

7369	张三	研发	800.00	30
7499	李四	财务	1600.00	20
7521	王五	行政	1250.00	10
7566	赵六	销售	2975.00	40
7654	侯七	研发	1250.00	30
7698	马八	研发	2850.00	30
7782	金九	\N	2450.0	30
7788	银十	行政	3000.00	10
7839	小芳	销售	5000.00	40
7844	小明	销售	1500.00	40
7876	小李	行政	1100.00	10
7900	小元	讲师	950.00	30
7902	小海	行政	3000.00	10
7934	小红明	讲师	1300.00	30

1创建部门表

create table if not exists dept(
    deptno int,
    dname string,
    loc int
)
row format delimited fields terminated by '\t';

2创建员工表

hive (default)>
create table if not exists emp(
    empno int,      -- 员工编号
    ename string,   -- 员工姓名
    job string,     -- 员工岗位大数据工程师、前端工程师、java工程师
    sal double,     -- 员工薪资
    deptno int      -- 部门编号
)
row format delimited fields terminated by '\t';

3导入数据

hive (default)>
load data local inpath '/opt/module/hive/datas/dept.txt' into table dept;
load data local inpath '/opt/module/hive/datas/emp.txt' into table emp;

2.1 全表和特定列查询

1全表查询

hive (default)> select * from emp;

2选择特定列查询

hive (default)> select empno, ename from emp;

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

2.2 列别名

1重命名一个列
2便于计算
3紧跟列名也可以在列名和别名之间加入关键字‘AS’
4案例实操

查询名称和部门。

hive (default)> 
select 
    ename AS name, 
    deptno dn 
from emp;

2.3 Limit语句

典型的查询会返回多行数据。limit子句用于限制返回的行数。

hive (default)> select * from emp limit 5; 
hive (default)> select * from emp limit 2,3; -- 表示从第2行开始向下抓取3

2.4 Where语句

1使用where子句将不满足条件的行过滤掉
2where子句紧随from子句
3案例实操

查询出薪水大于1000的所有员工。

hive (default)> select * from emp where sal > 1000;

注意where子句中不能使用字段别名。

2.5 关系运算函数

1基本语法

如下操作符主要用于where和having语句中。

操作符支持的数据类型描述
A=B基本数据类型如果A等于B则返回true反之返回false
A<=>B基本数据类型如果A和B都为null或者都不为null则返回true如果只有一边为null返回false
A<>B, A!=B基本数据类型A或者B为null则返回null如果A不等于B则返回true反之返回false
A<B基本数据类型A或者B为null则返回null如果A小于B则返回true反之返回false
A<=B基本数据类型A或者B为null则返回null如果A小于等于B则返回true反之返回false
A>B基本数据类型A或者B为null则返回null如果A大于B则返回true反之返回false
A>=B基本数据类型A或者B为null则返回null如果A大于等于B则返回true反之返回false
A [not] between B and C基本数据类型如果AB或者C任一为null则结果为null。如果A的值大于等于B而且小于或等于C则结果为true反之为false。如果使用not关键字则可达到相反的效果。这个区间左右都是闭区间
A is null所有数据类型如果A等于null则返回true反之返回false
A is not null所有数据类型如果A不等于null则返回true反之返回false
in数值1数值2所有数据类型使用 in运算显示列表中的值in后面的括号里面是集合可以跟上多个数字。
A [not] like Bstring 类型B是一个SQL下的简单正则表达式也叫通配符模式如果A与其匹配的话则返回true反之返回false。B的表达式说明如下‘x%’表示A必须以字母‘x’开头‘%x’表示A必须以字母‘x’结尾而‘%x%’表示A包含有字母‘x’,可以位于开头结尾或者字符串中间。如果使用not关键字则可达到相反的效果。
A rlike B, A regexp Bstring 类型B是基于java的正则表达式如果A与其匹配则返回true反之返回false。匹配使用的是JDK中的正则表达式接口实现的因为正则也依据其中的规则。例如正则表达式必须和整个字符串A相匹配而不是只需与其字符串匹配。
  • 通配表达式%表示任意个任意字符_下划线表示一个任意字符。

2.6 逻辑运算函数

1基本语法and/or/not

操作符含义
and逻辑并
or逻辑或
not逻辑否

2案例实操

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);

2.7 聚合函数

1语法

count(*)表示统计所有行数包含nullcount(某列)表示该列一共有多少行不包含nullmax()求最大值不包含null除非所有值都是null
min()求最小值不包含null除非所有值都是null
sum()求和不包含nullavg()求平均值不包含null
  • 聚合函数可以把多行数据聚合在一起进行计算并返回计算后的数值。
    在这里插入图片描述
  • local表示的是本地模式即所有的mapTask和reduceTask都运行在一个节点的一个进程里面。
  • mapreduce正常情况下是一个分布式的计算程序可能会有多个map和多个reduce。map和reduce可能运行在多个不同的节点上面。

在这里插入图片描述
在这里插入图片描述

2案例实操

1求总行数count

hive (default)> select count(*) cnt from emp;

hive sql执行过程

在这里插入图片描述
2求工资的最大值max

hive (default)> select max(sal) max_sal from emp;

hive sql执行过程

在这里插入图片描述
3求工资的最小值min

hive (default)> select min(sal) min_sal from emp;

hive sql执行过程

在这里插入图片描述
4求工资的总和sum

hive (default)> select sum(sal) sum_sal from emp; 

hive sql执行过程
在这里插入图片描述

5求工资的平均值avg

hive (default)> select avg(sal) avg_sal from emp;

hive sql执行过程

在这里插入图片描述

3、分组

3.1 Group By语句

Group By语句通常会和聚合函数一起使用按照一个或者多个列队结果进行分组然后对每个组执行聚合操作。

计算每个部门有多少人

select job,count(*) from emp
group by job;
  • 分组首先会首先按照指定的字段进行分组之后的count(*)会应用在每一组里面。
  • 最后返回多少行数据有多少组就会返回多少行因为对每组都使用了一次聚合函数聚合之后每组返回一行。
  • 注意对于分组聚合select的字段只能有两类一类是聚合函数另一类就是分组的字段。

1案例实操

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

hive (default)> 
select 
    t.deptno, 
    avg(t.sal) avg_sal 
from emp t 
group by t.deptno;

2计算emp每个部门中每个岗位的最高薪水。

hive (default)>
select 
    t.deptno, 
    t.job, 
    max(t.sal) max_sal 
from emp t 
group by t.deptno, t.job;

3.2 Having语句

1having与where不同点

1where后面不能写分组聚合函数而having后面可以使用分组聚合函数。【因为where过滤的是表里面的一行一行的数据而group by之后返回的是一组一组的数据。】

2having只用于group by分组统计语句。

2案例实操

1求每个部门的平均薪水大于2000的部门

①求每个部门的平均工资。

hive (default)> 
select 
    deptno, 
    avg(sal) 
from emp 
group by deptno;

②求每个部门的平均薪水大于2000的部门。

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

3.3 Join语句

在这里插入图片描述

1等值与不等值Join

Hive支持通常的sql join语句但是只支持等值连接hive的某些版本不支持非等值连接。

1案例实操

1根据员工表和部门表中的部门编号相等查询员工编号、员工名称和部门名称。

hive (default)> 
select 
    e.empno, 
    e.ename, 
    d.dname 
from emp e 
join dept d 
on e.deptno = d.deptno;

在这里插入图片描述
等值与不等值连接

在这里插入图片描述

2表的别名

1好处

1使用别名可以简化查询。

2区分字段的来源。

2案例实操

合并员工表和部门表。

hive (default)> 
select 
    e.*,
    d.* 
from emp e 
join dept d 
on e.deptno = d.deptno;

3内连接

内连接只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。
在这里插入图片描述

hive (default)> 
select 
    e.empno, 
    e.ename, 
    d.deptno 
from emp e 
join dept d 
on e.deptno = d.deptno;

4左外连接

左外连接join操作符左边表中符合where子句的所有记录将会被返回。
在这里插入图片描述

hive (default)> 
select 
    e.empno, 
    e.ename, 
    d.deptno 
from emp e 
left join dept d 
on e.deptno = d.deptno;

5右外连接

右外连接join操作符右边表中符合where子句的所有记录将会被返回。

hive (default)> 
select 
    e.empno, 
    e.ename, 
    d.deptno 
from emp e 
right join dept d 
on e.deptno = d.deptno;

6满外连接

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

hive (default)> 
select 
    e.empno, 
    e.ename, 
    d.deptno 
from emp e 
full join dept d 
on e.deptno = d.deptno;

7多表连接

注意连接n个表至少需要n-1个连接条件。例如连接三个表至少需要两个连接条件。

数据准备在/opt/module/hive/datas/下vim location.txt

部门位置id 部门位置

[root@hadoop102 datas]$ vim location.txt
1700	北京
1800	上海
1900	深圳

1创建位置表

hive (default)>
create table if not exists location(
    loc int,           -- 部门位置id
    loc_name string   -- 部门位置
)
row format delimited fields terminated by '\t';

2导入数据

hive (default)> load data local inpath '/opt/module/hive/datas/location.txt' into table location;

3多表连接查询

hive (default)> 
select 
    e.ename, 
    d.dname, 
    l.loc_name
from emp e 
join dept d
on d.deptno = e.deptno 
join location l
on d.loc = l.loc;

大多数情况下Hive会对每对join连接对象启动一个MapReduce任务。本例中会首先启动一个MapReduce job对表e和表d进行连接操作然后会再启动一个MapReduce job将第一个MapReduce job的输出和表l进行连接操作。

注意为什么不是表d和表l先进行连接操作呢这是因为Hive总是按照从左到右的顺序执行的。

在这里插入图片描述

8笛卡尔集

1笛卡尔集会在下面条件下产生

1省略连接条件

2连接条件无效

3所有表中的所有行互相连接

2案例实操

hive (default)> 
select 
    empno, 
    dname 
from emp, dept;

9联合union & union all

在这里插入图片描述

1union&union all上下拼接

union和union all都是上下拼接sql的结果这点是和join有区别的join是左右关联union和union all是上下拼接。union去重union all不去重。

  • 这里的去重指的是select得到的结果当中上下两部分数据有完全相同的。

union和union all在上下拼接sql结果时有两个要求

1两个sql的结果列的个数必须相同

2两个sql的结果上下所对应列的类型必须一致

2案例实操

将员工表30部门的员工信息和40部门的员工信息利用union进行拼接显示。

hive (default)> 
select 
    *
from emp
where deptno=30
union
select 
    *
from emp
where deptno=40;
  • union连接的不是两张表而是两个select查询。
  • 如果两张表的字段名不同则union之后会跟第一张表的字段名一样。

4、排序–4By

4.1 全局排序Order By

Order By全局排序只有一个Reduce。

1使用Order By子句排序

ascascend升序默认

descdescend降序

2Order By子句在select语句的结尾

3基础案例实操

1查询员工信息按工资升序排列

hive (default)> 
select 
    * 
from emp 
order by sal;

在这里插入图片描述

  • order by 一般和limit一起使用这样可以找出前几或者倒数第几。
  • 使用limit之后map阶段会进行优化这样就不用把所有的数据都给一个reduce了。

2查询员工信息按工资降序排列

hive (default)> 
select 
    * 
from emp 
order by sal desc;

4按照别名排序案例实操

按照员工薪水的2倍排序。

hive (default)> 
select 
    ename, 
    sal * 2 twosal 
from emp 
order by twosal;

hive sql执行过程

在这里插入图片描述

5多个列排序案例实操

按照部门和工资升序排序。

hive (default)> 
select 
    ename, 
    deptno, 
    sal 
from emp 
order by deptno, sal;

在这里插入图片描述

4.2 每个Reduce内部排序Sort By

Sort By对于大规模的数据集order by的效率非常低。在很多情况下并不需要全局排序此时可以使用Sort by。

Sort by为每个reduce产生一个排序文件。每个Reduce内部进行排序对全局结果集来说不是排序。

1设置reduce个数

hive (default)> set mapreduce.job.reduces=3;

2查看设置reduce个数

hive (default)> set mapreduce.job.reduces;

3根据部门编号降序查看员工信息

hive (default)> 
select 
    * 
from emp 
sort by deptno desc;

在这里插入图片描述
4将查询结果导入到文件中按照部门编号降序排序

hive (default)> insert overwrite local directory '/opt/module/hive/datas/sortby-result'
 select * from emp sort by deptno desc;
  • 面试题order by和sort by 的区别是什么 order by 声明的是全局的排序字段而sort by 如果使用在transfome语句当中指定的是从map到reduce阶段的排序字段。能够保证数据到达reduce的时候按照字段进行排序。

1、order by会对输入做全局排序因此只有1个reducer多个reducer无法保证全局有序会导致当输入规模较大时需要较长的计算时间。

2、sort by不是全局排序其在数据进入 reducer 前完成排序。

因此如果用 sort by 进行排序并且设置 mapred.reduce.tasks>1 则 sort by 只保证每个 reducer 的输出有序不保证全局有序。

4.3 分区Distribute By

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

1案例实操

1先按照部门编号分区再按照员工编号薪资排序

hive (default)> set mapreduce.job.reduces=3;
hive (default)> 
insert overwrite local directory 
'/opt/module/hive/datas/distribute-result' 
select 
    * 
from emp 
distribute by deptno  --分区字段是deptno
sort by sal desc;   --排序字段是sal

注意

  • distribute by的分区规则是根据分区字段的hash码与reduce的个数进行相除后余数相同的分到一个区。
  • Hive要求distribute by语句要写在sort by语句之前。
  • 演示完以后mapreduce.job.reduces的值要设置回-1否则下面分区or分桶表load跑MapReduce的时候会报错。

在这里插入图片描述

4.4 分区排序Cluster By

当distribute by和sort 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号部门分到一个分区里面去。

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6