Hive 查詢的 18 種方式
前言
相信大家一定對 Hive 不陌生!Hive 是基於Hadoop 的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供類SQL查詢功能(HQL)。Hive的優點是學習成本低,可以通過類似SQL語句實現快速MapReduce統計,使MapReduce變得更加簡單,而不必開發專門的MapReduce應用程式。因此,hive十分適合對資料倉庫進行統計分析。
我們就來探討一下,關於Hive資料查詢的18種方式!
準備
我們本期內容大部分HQL操作都需要依賴如下兩張表,具體的資料內容如下:
course student1、SELECT查詢語句
SELECT 查詢語句比較簡單,後面跟要查詢的欄位,如下所示:
hive (hypers)> selectnamefrom 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, namefrom 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 limit1; OK student.stuid student.name student.sex student.age 15317408 Rose 1 21可以使用ORDER BY語句對結果進行排序,升序我們可以不在排序的欄位後加上ASC(預設),但是倒序需要指定DESC,如下所示:
hive (hypers)> select * from student orderby 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 orderby 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 21WHERE 條件語句常用的操作符如該表所示
操作符 | 支援的資料型別 | 說明 |
---|---|---|
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 groupby sex; OK sex _c1 0 19.666666666666668 1 20.6666666666666684、HAVING語句
HAVING語句主要用來對GROUP BY語句的結果進行條件限制,如下所示:
hive (hypers)> select sex,avg(age) from student groupby sex havingavg(age) > 20; OK sex _c1 1 20.6666666666666685、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 leftouterjoin course t2 on t1.stuid = t2.stuid; OK t1.name t2.coursename Rose C語言 Jack Java Jimmy 高等數學 Tom 離散數學 Jerry C++ Alice NULL7、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 FULLouterjoin 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 LEFTSEMIJOIN 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 orderby 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 orderby age asc,stuId desclimit100; 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 sortby age asc,stuId desclimit100; 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 distributeby sex sortby 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 21DISTRIBUTE BY語句能夠保證sex相同的資料進入同一個 Reduce 函式,在 Reduce中再按照 age 和 stuId 排序即可實現在第一列資料相同時,按照第二列資料排序。
15、CLUSTER BY語句
如果 DISTRIBUTE BY 和 SORT BY 語句中的列完全相同,並且都是按照升序排序,則可以使用CLUSTER BY語句代替DISTRIBUTE BY和SORT BY語句,如下所示:
select * from student distributeby age sortby 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 2116、型別轉換
型別轉換可以使用 cast(value As TYPE)語法,如下所示:
hive (hypers)> select * from student wherecast(stuId ASINT) >= 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 (BUCKET2OUTOF6ON stuid); OK student.stuid student.name student.sex student.age 15317467 Alice 0 20上述語句表示查詢時分6個桶,取第2個桶,分桶的依據是將id值的雜湊值除以桶數6的餘數。也可以採用隨機抽樣的方式,如下所示:
hive (hypers)> SELECT * FROM student TABLESAMPLE (BUCKET2OUTOF6ONRAND()); 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)> CREATETABLE test_bucket(idINT) CLUSTERED BY (id) INTO3 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語句,必須使用巢狀查詢 。|