我們本期內容大部分HQL操作都需要依賴如下兩張表,具體的數據內容如下:
course
student
1、SELECT查詢語句
SELECT 查詢語句比較簡單,后面跟要查詢的字段,如下所示:
hive (hypers)> select name from student;
OK
name
Rose
Jack
Jimmy
Tom
Jerry
可以為查詢語句中的列和表加上別名,如下所示:
hive (hypers)> select t.name from student t;
OK
t.name
Rose
Jack
Jimmy
Tom
Jerry
可以使用如下語句進行嵌套查詢:
hive (hypers)> select a.name, b.coursename
> from (select stuid, name from student) a
> join (select stuid, coursename from course) b on a.stuid = b.stuid;
OK
a.name b.coursename
Rose C語言
Jack Java
Jimmy 高等數學
Tom 離散數學
Jerry C++
可以使用正則表達式指定查詢的列,如下所示:
hive (hypers)> select t.* from student t;
OK
t.stuid t.name t.sex t.age
15317408 Rose 1 21
15317412 Jack 0 20
15317432 Jimmy 1 21
15317423 Tom 1 20
15317478 Jerry 0 19
15317467 Alice 0 20
可以使用 LIMIT
限制查詢的結果條數,如下所示:
hive (hypers)> select * from student limit 1;
OK
student.stuid student.name student.sex student.age
15317408 Rose 1 21
可以使用ORDER BY
語句對結果進行排序,升序我們可以不在排序的字段后加上ASC
(默認),但是倒序需要指定DESC
,如下所示:
hive (hypers)> select * from student order by age desc;
OK
student.stuid student.name student.sex student.age
15317432 Jimmy 1 21
15317408 Rose 1 21
15317467 Alice 0 20
15317423 Tom 1 20
15317412 Jack 0 20
15317478 Jerry 0 19
Time taken: 10.631 seconds, Fetched: 5 row(s)
hive (hypers)> select * from student order by age;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317467 Alice 0 20
15317423 Tom 1 20
15317412 Jack 0 20
15317432 Jimmy 1 21
15317408 Rose 1 21
我們還可以使用CASE...WHEN...THEN
語句對某一列的值進行處理,如下所示:
hive (hypers)> SELECT stuid,
> name,
> age,
> sex,
> CASE
> WHEN sex = '1' THEN '男'
> WHEN sex = '0' THEN '女'
> ELSE '未知'
> END
> FROM student;
OK
stuid name age sex _c4
15317408 Rose 21 1 男
15317412 Jack 20 0 女
15317432 Jimmy 21 1 男
15317423 Tom 20 1 男
15317478 Jerry 19 0 女
15317478 Alice 20 0 女
2、WHERE 條件語句
WHERE 條件語句主要是對查詢進行條件限制,如下所示:
hive (hypers)> select * from student where age = 21;
OK
student.stuid student.name student.sex student.age
15317408 Rose 1 21
15317432 Jimmy 1 21
WHERE 條件語句常用的操作符如該表所示 | 操作符 | 支持的數據類型 | 說明 |
---|---|---|---|
A=B | 基本數據類型 | 如果A等於B,則返回true,否則返回false | |
A<=>B | 基本數據類型 | 如果A和B都為NULL,則返回true,其他情況和 A=B 相同 | |
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 IS NULL | 所有數據類型 | 如果A為NULL返回true,否則返回 false | |
A IS NOT NULL | 所有數據類型 | 如果A不為NULL返回true,否則返回 false | |
A BETWEEN B AND C | 基本數據類型 | 如果A、B、C任一為NULL,則返回NULL;如果A大於或者等於B並且A小於或等於C,則返回true,否則返回false | |
A NOT BETWEEN B AND C | 基本數據類型 | 如果A、B、C任一為NULL,則返回NULL;如果A小於B或者A大於C,則返回true,否則返回false | |
A LIKE B | STRING類型 | 如果A模糊匹配B,則返回true,否則返回false | |
A NOT LIKE B | STRING類型 | 如果A不模糊匹配B,則返回true,否則返回false | |
A RLIKE B,A REGEXP B | STRING類型 | B是一個正則表達式,如果A匹配正則表達式,則返回true,否則返回false |
3、GROUP BY 語句
GROUP BY
語句主要是對查詢的數據進行分組,通常會和聚合函數一起使用,如下所示:
hive (hypers)> select sex,avg(age) from student group by sex;
OK
sex _c1
0 19.666666666666668
1 20.666666666666668
4、HAVING語句
HAVING
語句主要用來對GROUP BY
語句的結果進行條件限制,如下所示:
hive (hypers)> select sex,avg(age) from student group by sex having avg(age) > 20;
OK
sex _c1
1 20.666666666666668
5、INNER JOIN語句
在 INNER JOIN
語句中,只有進行連接的兩個表中都存在與連接條件相匹配的數據時才會被顯示在結果數據中,如下所示:
hive (hypers)> select t1.name,t2.coursename from student t1 join course t2 on t1.stuid = t2.stuid;
OK
t1.name t2.coursename
Rose C語言
Jack Java
Jimmy 高等數學
Tom 離散數學
Jerry C++
6、 LEFT OUTER JOIN語句
LEFT OUTER JOIN
語句表示左外連接,左外連接查詢數據會包含左表中的全部記錄,而右表中不符合條件的結果將以NULL
的形式出現,如下所示:
hive (hypers)> select t1.name,t2.coursename from student t1 left outer join course t2 on t1.stuid = t2.stuid;
OK
t1.name t2.coursename
Rose C語言
Jack Java
Jimmy 高等數學
Tom 離散數學
Jerry C++
Alice NULL
7、RIGHT OUTER JOIN語句
RIGHT OUTER JOIN
表示右外連接,右外連接查詢數據會包含右表中的全部記錄,而左表中不符合條件的結果將以 NULL 的形式出現,如下所示:
hive (hypers)> select t1.name,t2.coursename from student t1 right outer join course t2 on t1.stuid = t2.stuid;
OK
t1.name t2.coursename
Rose C語言
Jack Java
Jimmy 高等數學
Tom 離散數學
Jerry C++
NULL 大數據應用開發
8、FULL OUTER JOIN語句
FULL OUTER JOIN
語句表示全外連接,結果數據會包含左表和右表的全部數據,不符合條件的用NULL表示,如下所示:
hive (hypers)> select t1.name,t2.coursename from student t1 FULL outer join course t2 on t1.stuid = t2.stuid;
OK
t1.name t2.coursename
Rose C語言
Jack Java
Tom 離散數學
Jimmy 高等數學
NULL 大數據應用開發
Alice NULL
Jerry C++
9、 LEFT SEMI JOIN語句
LEFT SEMI JOIN
語句表示左半連接,其結果數據對應右表滿足 ON 語句中的條件,如下所示:
hive (hypers)> select t1.name from student t1 LEFT SEMI JOIN course t2 on t1.stuid = t2.stuid;
OK
t1.name
Rose
Jack
Jimmy
Tom
Jerry
注意:| 在 LEFT SEMI JOIN 語句中,SELECT 和 WHERE 子句中不能引用右表中的字段。|
10、笛卡爾積 JOIN 語句
笛卡爾積 JOIN 語句 表示左表的行數乘以右表的行數等於結果集的大小,如下所示:
hive (hypers)> select * from student join course;
OK
student.stuid student.name student.sex student.age course.stuid course.coursename course.score
15317408 Rose 1 21 15317408 C語言 50
15317412 Jack 0 20 15317408 C語言 50
15317432 Jimmy 1 21 15317408 C語言 50
15317423 Tom 1 20 15317408 C語言 50
15317478 Jerry 0 19 15317408 C語言 50
15317467 Alice 0 20 15317408 C語言 50
15317408 Rose 1 21 15317412 Java 60
15317412 Jack 0 20 15317412 Java 60
15317432 Jimmy 1 21 15317412 Java 60
15317423 Tom 1 20 15317412 Java 60
15317478 Jerry 0 19 15317412 Java 60
15317467 Alice 0 20 15317412 Java 60
15317408 Rose 1 21 15317432 高等數學 70
15317412 Jack 0 20 15317432 高等數學 70
15317432 Jimmy 1 21 15317432 高等數學 70
15317423 Tom 1 20 15317432 高等數學 70
15317478 Jerry 0 19 15317432 高等數學 70
15317467 Alice 0 20 15317432 高等數學 70
15317408 Rose 1 21 15317423 離散數學 80
15317412 Jack 0 20 15317423 離散數學 80
15317432 Jimmy 1 21 15317423 離散數學 80
15317423 Tom 1 20 15317423 離散數學 80
15317478 Jerry 0 19 15317423 離散數學 80
15317467 Alice 0 20 15317423 離散數學 80
15317408 Rose 1 21 15317478 C++ 90
15317412 Jack 0 20 15317478 C++ 90
15317432 Jimmy 1 21 15317478 C++ 90
15317423 Tom 1 20 15317478 C++ 90
15317478 Jerry 0 19 15317478 C++ 90
15317467 Alice 0 20 15317478 C++ 90
15317408 Rose 1 21 15317463 大數據應用開發 100
15317412 Jack 0 20 15317463 大數據應用開發 100
15317432 Jimmy 1 21 15317463 大數據應用開發 100
15317423 Tom 1 20 15317463 大數據應用開發 100
15317478 Jerry 0 19 15317463 大數據應用開發 100
15317467 Alice 0 20 15317463 大數據應用開發 100
注意:| 如果將 Hive 的屬性hive.mapred.mode 設置為 strict,則會阻止執行笛卡爾積查詢。 |
11、map-side JOIN語句
map-site JOIN語句會在Map階段將小表讀到內存,直接在 Map 端 進行JOIN,這種連接需要在查詢語句中顯式申明,如下所示:
SELECT /* + MapJOIN(t1) */ s1.stuid,s2.stuid from student s1 JOIN student s2 ON s1.stuid = s2.stuid;
可以通過設置Hive的屬性 hive.auto.convert.join=true
自動開啟 map-side JOIN
;也可以設置 Hive 的屬性 hive.mapjoin.smalltable.filesize
定義表的大小,默認為 25 000 000 B。
12、多表JOIN語句
Hive支持多張表進行連接,語句如下所示:
hive (hypers)> SELECT *
FROM test1 t1
JOIN test2 t2 ON t1.id = t2.id
JOIN test3 t3 ON t2.id = t3.id
每個 JOIN 都會啟動一個 MapReduce 作業。第一個MapReduce作業連接 test1 表和 test2 表,第二個MapReduce作業連接第一個MapReduce作業的輸出結果和 test3 表。
13、ORDER BY 和 SORT BY 語句
Hive中的 ORDER BY
語句和SQL
語句一樣,可以實現對結果集的排序,如下所示:
hive (hypers)> select * from student order by age asc,stuId desc;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317467 Alice 0 20
15317423 Tom 1 20
15317412 Jack 0 20
15317432 Jimmy 1 21
15317408 Rose 1 21
Time taken: 11.929 seconds, Fetched: 6 row(s)
上述語句表示按照age字段升序,stuId字段降序排序。
如果Hive表中的數據非常多,使用 ORDER BY
排序可能會導致執行的時間過長,此時可以設置Hive的屬性 hive.mapred.mode
為strict,則排序語句后面必須加上 LIMIT
限制查詢的結果條數,以避免數據量太多造成的執行時間過長的問題,如下所示:
hive (hypers)> SET hive.mapred.mode = strict;
hive (hypers)> select * from student order by age asc,stuId desc limit 100;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317467 Alice 0 20
15317423 Tom 1 20
15317412 Jack 0 20
15317432 Jimmy 1 21
15317408 Rose 1 21
Time taken: 9.378 seconds, Fetched: 6 row(s)
SORT BY
語句會在每個Reduce中對數據進行排序,可以保證每個Reduce輸出的數據是有序的(全局不一定有序),並可以提高全局排序的性能,如下所示:
hive (hypers)> select * from student sort by age asc,stuId desc limit 100;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317467 Alice 0 20
15317423 Tom 1 20
15317412 Jack 0 20
15317432 Jimmy 1 21
15317408 Rose 1 21
上述語句會在每個Reduce中對age字段進行升序排序,同時對create_time
字段進行降序排序。如果Reduce個數為1,則ORDER BY
和SORT BY
語句的查詢結果相同;如果Reduce個數大於1,則SORT BY
輸出的結果為局部有序。
14、 DISTRIBUTE BY 和 SORT BY語句
DISTRIBUTE
語句結合SORT BY
語句可以實現在第一列數據相同時,能夠按照第二列數據進行排序,如下所示:
hive (hypers)> select * from student distribute by sex sort by age,stuId;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317412 Jack 0 20
15317423 Tom 1 20
15317467 Alice 0 20
15317408 Rose 1 21
15317432 Jimmy 1 21
DISTRIBUTE BY
語句能夠保證sex相同的數據進入同一個 Reduce 函數,大數據培訓在 Reduce中再按照 age 和 stuId 排序即可實現在第一列數據相同時,按照第二列數據排序。
15、CLUSTER BY語句
如果 DISTRIBUTE BY
和 SORT BY
語句中的列完全相同,並且都是按照升序排序,則可以使用CLUSTER BY
語句代替DISTRIBUTE BY
和SORT BY
語句,如下所示:
select * from student distribute by age sort by age;
上面的語句等價於:
hive (hypers)> select * from student cluster by age;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317467 Alice 0 20
15317423 Tom 1 20
15317412 Jack 0 20
15317432 Jimmy 1 21
15317408 Rose 1 21
16、類型轉換
類型轉換可以使用 cast(value As TYPE)
語法,如下所示:
hive (hypers)> select * from student where cast(stuId AS INT) >= 15317450;
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
15317467 Alice 0 20
上述語句表示將 stuId 轉化為 INT 類型。
17、分桶抽樣
Hive支持分桶抽樣查詢,如下所示:
hive (hypers)> SELECT * FROM student TABLESAMPLE (BUCKET 2 OUT OF 6 ON stuid);
OK
student.stuid student.name student.sex student.age
15317467 Alice 0 20
上述語句表示查詢時分6個桶,取第2個桶,分桶的依據是將id值的哈希值除以桶數6的余數。也可以采用隨機抽樣的方式,如下所示:
hive (hypers)> SELECT * FROM student TABLESAMPLE (BUCKET 2 OUT OF 6 ON RAND());
OK
student.stuid student.name student.sex student.age
15317478 Jerry 0 19
Time taken: 0.04 seconds, Fetched: 1 row(s)
可以在創建表時指定分桶,需要提前將 Hive 的 hive.enforce.bucketing
屬性設置為 true。該屬性可以在 hive-site.xml
文件中配置,如下所示:
<property>
<name>hive.enforce.bucketing</name>
<value>true</value>
</property>
也可以在Hive命令行設置,如下所示:
hive (default)> SET hive.enforce.bucketing = true;
創建表時指定分桶,並插入 student 表中的 id列數據,如下所示:
hive (hypers)> CREATE TABLE test_bucket(id INT) CLUSTERED BY (id) INTO 3 BUCKETS ;
OK
Time taken: 0.086 seconds
hive (hypers)> INSERT OVERWRITE TABLE test_bucket SELECT stuid FROM student;
OK
stuid
Time taken: 24.261 seconds
上述語句首先創建一個 test_bucket
表,並將 test_bucket
表划分為3個桶,然后將 student 表中的 id 列數據插入 test_bucket
表中。插入的數據會被保存在3個文件中,每個桶一個文件,保存在 test_bucket
表路徑下。
18、 UNION ALL 語句
Hive 支持 UNION ALL
查詢,其主要用於多表數據合並的場景。使用 UNION ALL
語句要求各表查詢出的字段類型必須完全匹配,如下所示:
SELECT t.id,t.name
FROM (
SELECT t1.id,t1.name FROM test1 t1
UNION ALL
SELECT t2.id,t2.name FROM test2 t2
UNION ALL
SELECT t3.id,t3.name FROM test3 t3
) t
注意:| 在Hive中使用
UNION ALL
語句,必須使用嵌套查詢 。 |