学科分类
目录
Hadoop技术栈

Hive数据操作

Hive数据操作是负责对数据库对象运行数据访问工作的指令集,通俗的讲它的功能就是操作数据,其中包括向数据表加载文件、写查询结果等。

在所有数据库系统中,查询语句是使用最频繁的,也是最复杂的,Hive中的Select语句与MySQL语法基本一致,且支持where、distinct、group by、order by、having、limit以及子查询等,下面是一个标准的Select语句语法格式:

SELECT [ALL | DISTINCT] select_expr, select_expr, ... 

FROM table_reference

JOIN table_other ON expr

[WHERE where_condition] 

[GROUP BY col_list [HAVING condition]] 

[CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]] 

[LIMIT number]

​ 接下来针对上述语法格式中的关键字分别讲解。

  • table_reference它可以是一张表,一个视图或者是一个子查询语句。
  • where关键字作为可选参选,用于指定查询条件。
  • distinct关键字用于剔除查询结果中重复的数据,如果没有定义则全部输出,默认为all;
  • group by用于将查询结果按照指定字段进行分组。
  • having作为可选参数,与group by关键字连用,它是将分组后的结果进行过滤;
  • distribute by是根据指定字段分发到不同的reducer进行处理,且分发算法采用哈希散列,它类似MapReduce中的partition分区,通常结合sort by使用。
  • sort by是在数据进入Reducer前完成排序,因此不是全局排序,如果设置mapred.reduce.tasks>1,则sort by只能保证每个reducer的输出有序,不保证全局有序。
  • cluster by是一个分桶查询语句,根据指定的字段进行分桶,分桶数取决于设置reduces个数,并且分桶后,每桶数据都会进行排序;通俗的讲,如果distribute和sort的字段是同一个时,此时可以理解为distribute by+sort by= cluster by。
  • order by用于将查询结果按照指定字段进行全局排序,因此输出文件只有一个,且只存在一个Reducer,那么当数据量很大时,就需要较长的计算时间。

在Hive中,HQL是不区分大小写的,但是关键字不能被缩写,也不能被分行,下面演示相关查询案例,首先准备数据dept.txt和emp.txt如文件1和文件2所示:

文件1 emp.txt

7369  SMITH  CLERK  7902  1980-12-17 800.00   20

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

文件2 dept.txt

10 ACCOUNTING 1700

20 RESEARCH  1800

30 SALES  1900

40 OPERATIONS 1700

并根据两个结构化数据文件创建对应表结构,代码如下所示:

创建emp表

hive> create table emp(empno int,ename string,job string,mgr int,

hiredate string, sal double, comm double,deptno int)

row format delimited fields terminated by '\t';

创建dept表

hive> create table dept(deptno int,dname string,loc int) 

row format delimited fields terminated by '\t';

创建表完成后,将数据文件移动到对应的表所在HDFS路径下,完成数据映射。

例1:基本查询

(1)全表查询:

hive> select * from emp;

(2)选择特定字段查询:

hive> select deptno,dname from dept;

(3)查询员工表总人数:

hive> select count(*) cnt from emp;

(4)查询员工表总工资额:

hive> select sum(sal) sum_sal from emp;

(5)查询5条员工表的信息

hive> select * from emp limit 5;

例2:Where条件查询

(1)查询出薪水等于5000的所有员工

hive> select * from emp where sal =5000;

(2)查询工资在500到1000的员工信息

hive> select * from emp where sal between 500 and 1000;

(3)查询comm为空的所有员工信息

hive> select * from emp where comm is null;

(4)查询工资是1500和5000的员工信息

hive> select * from emp where sal IN (1500, 5000);

例3:Like和Rlike

RLike子句是Hive中这个功能的一个扩展,其可以通过Java的正则表达式来指定匹配条件。

(1)查找以2开头薪水的员工信息

hive> select * from emp where sal LIKE '2%';

(2)查找第二个数值为2的薪水的员工信息

hive> select * from emp where sal LIKE '_2%';

(3)查找薪水中含有2的员工信息

hive> select * from emp where sal RLIKE '[2]';

例4:Group By语句

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

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

hive> select t.deptno,avg(t.sal) avg_sal 

from emp t group by t.deptno;

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

hive> select t.deptno,t.job,max(t.sal) max_sal 

from emp t group by t.deptno, t.job;

例5:Having语句

Having和Where语句虽然都是根据条件进行筛选过滤,但是它们之间有许多不同之处。

  • Where针对表中的列进行条件过滤,查询数据,Having针对查询结果中的列进行条件过滤,筛选数据;
  • Where后面不能写分组函数,而Having后面可以使用分组函数。
  • Having只用于Group by分组统计语句。

(1)求每个部门的平均工资

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

(2)求每个部门的平均薪水大于2000的部门

hive> select deptno, avg(sal) avg_sal

from emp group by deptno having avg_sal > 2000;

例6:Order by语句

Order by默认为升序(ASC),降序为(DESC)。

(1)查询员工信息按工资降序排列

hive> select * from emp order by sal desc;

(2)按照部门和工资升序排序

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

例7:Sort by语句

(1)设置reduce个数

hive> set mapreduce.job.reduces=3;

(2)查看设置reduce个数

hive> set mapreduce.job.reduces;

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

hive> select * from emp sort by empno desc;

(4)将查询结果导入到文件中(按照部门编号降序排序)

hive> insert overwrite local directory '/root/sortby-result' 

select * from emp sort by deptno desc;

例8:Distribute By

Distribute By通常与Sort By结合使用,但是要注意Distribute By语句要写在Sort By语句之前,对于Distribute By进行测试,一定要分配多个Reduce进行处理,否则无法看到Distribute By的效果。

(1)先按照部门编号分区,再按照员工编号降序排序。

hive> set mapreduce.job.reduces=3;

hive> insert overwrite local directory '/root/distribute-result' 

select * from emp distribute by deptno sort by empno desc;

例9:Cluster By

Cluster by除了具有Distribute By的功能外还兼具Sort By的功能,但是排序只能是倒序排序,不能指定排序规则为ASC或者DESC。

以下两种写法等价

hive> select * from emp cluster by deptno;

hive> select * from emp distribute by deptno sort by deptno;

例10:Join操作

在当前版本中,Hive只支持等值连接,因为非等值连接难以转化为MapReduce任务。

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

hive> select e.empno, e.ename, d.deptno, d.dname

from emp e join dept d on e.deptno = d.deptno;

左外连接:Join操作符左边表中符合条件的所有记录将会被返回。

hive> select e.empno, e.ename, d.deptno 

from emp e left join dept d on e.deptno = d.deptno;

右外连接:Join操作符右边表中符合条件的所有记录将会被返回。

hive> select e.empno, e.ename, d.deptno 

from emp e right join dept d on e.deptno = d.deptno;

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

hive> select e.empno, e.ename, d.deptno 

from emp e full join dept d on e.deptno = d.deptno;

在使用Join语句时,如果想限制输出结果,可以在Join语句后面添加Where语句,进行过滤。

hive> select e.empno, e.ename, d.deptno 

from emp e full join dept d on e.deptno = d.deptno where d.deptno=20;
点击此处
隐藏目录