Hive-HQL之DQL命令
DQL(Data Query Language):数据查询语言。
SQL语句书写注意事项:
SQL语句对大小写不敏感
SQL语句可以写一行(简单SQL)也可以写多行(复杂SQL)
关键字不能缩写,也不能分行
各子句一般要分行
使用缩进格式,提高SQL语句的可读性(重要)
创建表,加载数据
1 | -- 测试数据 /home/hadoop/data/emp.dat |
基本查询
select语法:
1 | SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference |
1 | -- 省略from子句的查询 |
where子句
WHERE子句紧随FROM子句,使用WHERE子句,过滤不满足条件的数据;
where 子句中不能使用列的别名;
1 | select * from emp where sal > 2000; |
where子句中会涉及到较多的比较运算和逻辑运算;
比较运算符
官方文档:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF
比较运算符 | 描述 |
---|---|
=、==、<=> | 等于 |
<>、!= | 不等于 |
<、<=、>、>= | 大于等于、小于等于 |
is [not] null | 如果A等于NULL,则返回TRUE,反之返回FALSE。使用NOT关键字结果相反。 |
in (value1,value2, …) | 匹配列表中的值 |
LIKE | 简单正则表达式,也称通配符模式。‘x%’ 表示必须以字母 ‘x’ 开头;‘%x’表示必须以字母’x’结尾;’%x%‘表示包含有字母’x’,可以位于字符串任意位置。使用NO关键字结果相反。% 代表匹配零个或多个字符(任意个字符);_ 代表匹配一个字符。 |
[NOT] BETWEEN … AND … | 范围的判断,使用NOT关键字结果相反。 |
RLIKE、REGEXP | 基于java的正则表达式,匹配返回TRUE,反之返回FALSE。匹配使用的是JDK中的正则表达式接口实现的,因为正则也依据其中的规则。例如,正则表达式必须和整个字符串A相匹配,而不是只需与其字符串匹配。 |
备注:通常情况下NULL参与运算,返回值为NULL;NULL<=>NULL的结果为true
逻辑运算符
1 | -- 比较运算符,null参与运算 |
group by子句
GROUP BY语句通常与聚组函数一起使用,按照一个或多个列对数据进行分组,对每个组进行聚合操作。
1 | -- 计算emp表每个部门的平均工资 |
-
where子句针对表中的数据发挥作用;having针对查询结果(聚组以后的结果)发挥作用
-
where子句不能有分组函数;having子句可以有分组函数
-
having只用于group by分组统计之后
1 | -- 求每个部门的平均薪水大于2000的部门 |
表连接
Hive支持通常的SQL JOIN语句。默认情况下,仅支持等值连接,不支持非等值连接。
JOIN 语句中经常会使用表的别名。使用别名可以简化SQL语句的编写,使用表名前缀可以提高SQL的解析效率。
连接查询操作分为两大类:内连接和外连接,而外连接可进一步细分为三种类型:
1 | 1. 内连接: [inner] join |
案例演示:
1 | -- 准备数据 u1.txt数据: |
多表连接
连接 n张表,至少需要 n-1 个连接条件。例如:连接四张表,至少需要三个连接条件。
多表连接查询,查询老师对应的课程,以及对应的分数,对应的学生:
1 | select * |
Hive总是按照从左到右的顺序执行,Hive会对每对 JOIN 连接对象启动一个MapReduce 任务。
上面的例子中会首先启动一个 MapReduce job 对表 t 和表 c 进行连接操作;然后再启动一个 MapReduce job 将第一个 MapReduce job 的输出和表 s 进行连接操作;然后再继续直到全部操作;
笛卡尔积
-
满足以下条件将会产生笛卡尔集:
没有连接条件
连接条件无效
所有表中的所有行互相连接
如果表A、B分别有M、N条数据,其笛卡尔积的结果将有 M*N 条数据;如下语句,执行报错:
1
select * from A, B;
原因:缺省条件下hive不支持笛卡尔积运算,我们可以关闭验证,支持笛卡尔积运算
1
set hive.strict.checks.cartesian.product=false;
排序子句
全局排序(order by)
order by 子句出现在select语句的结尾;
order by 子句对最终的结果进行排序;
默认使用升序(ASC);可以使用DESC,跟在字段名之后表示降序;
ORDER BY执行全局排序,只有一个reduce;
1 | -- 普通排序 |
每个MR内部排序(sort by)
对于大规模数据而言order by效率低;
在很多业务场景,我们并不需要全局有序的数据,此时可以使用sort by;
sort by为每个reduce产生一个排序文件,在reduce内部进行排序,得到局部有序的结果;
1 | -- 设置reduce个数 |
分区排序(distribute by)
distribute by 将特定的行发送到特定的reducer中,便于后继的聚合 与 排序操作;
distribute by 类似于MR中的分区操作,可以结合sort by操作,使分区数据有序;
distribute by 要写在sort by之前;
1 | -- 启动2个reducer task;先按 deptno 分区,在分区内按 sal+comm 排序 |
Cluster By
当distribute by 与 sort by是同一个字段时,可使用cluster by简化语法;
cluster by 只能是升序,不能指定排序规则;
1 | -- 语法上是等价的 |
排序小结
-
order by。执行全局排序,效率低。生产环境中慎用
-
sort by。使数据局部有序(在reduce内部有序)
-
distribute by。按照指定的条件将数据分组,常与sort by联用,使数据局部有序
-
cluster by。当distribute by 与 sort by是同一个字段时,可使用cluster by简化语法