Hive 之 函數 01-常用查詢函數(一)
- 一、 空字段指派
- 二、 時間類
-
- 2.1 date_format: 格式化時間
- 2.2 date_add: 時間跟天數相加
- 2.3 date_sub: 時間跟天數相減(跟 date_add 記一個就行)
- 2.4 datediff: 兩個時間相減
- 2.5 注意:
- 三、 case when
- 四、 行轉列
-
- 4.1 CONCAT
- 4.2 CONCAT_WS
- 4.3 COLLECT_SET
- 4.4 生産中的應用
- 五、 列轉行
-
- 5.1 EXPLODE
- 5.2 lateral view
- 5.3 額外拓展
一、 空字段指派
NVL 函數: 給值為 Null 的函數指派, 它的格式是
NVL(string1, replace_with)
, 它的功能是如果 string1 的值不為 Null, 則傳回 string1 的值, 否則, 将傳回 replace_with 的值, 如果 replace_with 的值也為 Null, 則傳回 Null。
hive (default)> select comm from emp;
OK
comm
NULL
300.0
500.0
NULL
1400.0
NULL
NULL
NULL
NULL
0.0
NULL
NULL
NULL
NULL
Time taken: 0.892 seconds, Fetched: 14 row(s)
hive (default)> select NVL(comm, '--') from emp;
OK
_c0
--
300.0
500.0
--
1400.0
--
--
--
--
0.0
--
--
--
--
Time taken: 0.072 seconds, Fetched: 14 row(s)
【注】NVL 函數的第二個參數也可以是表中的某個字段:
hive (default)> select empno, nvl(comm, empno) from emp;
OK
empno _c1
7369 7369.0
7499 300.0
7521 500.0
7566 7566.0
7654 1400.0
7698 7698.0
7782 7782.0
7788 7788.0
7839 7839.0
7844 0.0
7876 7876.0
7900 7900.0
7902 7902.0
7934 7934.0
Time taken: 0.112 seconds, Fetched: 14 row(s)
二、 時間類
2.1 date_format: 格式化時間
hive(default)> select date_format('1990-02-12', 'yyyy-MM-dd HH:mm:ss');
OK
_c0
1990-02-12 00:00:00
Time taken: 0.471 seconds, Fetched: 1 row(s)
2.2 date_add: 時間跟天數相加
hive (default)> select date_add('2020-02-26', 4);
OK
_c0
2020-03-01
Time taken: 0.154 seconds, Fetched: 1 row(s)
hive (default)> select date_add('2020-02-26', -4);
OK
_c0
2020-02-22
Time taken: 0.079 seconds, Fetched: 1 row(s)
2.3 date_sub: 時間跟天數相減(跟 date_add 記一個就行)
hive (default)> select date_sub('2020-02-26', 4);
OK
_c0
2020-02-22
Time taken: 0.103 seconds, Fetched: 1 row(s)
hive (default)> select date_sub('2020-02-26', -4);
OK
_c0
2020-03-01
Time taken: 0.069 seconds, Fetched: 1 row(s)
2.4 datediff: 兩個時間相減
第一個參數減去第二個參數。
hive(default)> select datediff('2020-03-03', '2020-02-28');
OK
_c0
4
Time taken: 0.125 seconds, Fetched: 1 row(s)
hive (default)> select datediff('2020-02-28', '2020-03-03');
OK
_c0
-4
Time taken: 0.057 seconds, Fetched: 1 row(s)
2.5 注意:
以上關于時間的計算隻接受中橫線作為時間的連接配接符, / 作為連接配接符的時間會得出 Null 的結果:
hive (default)> select date_add('2020/02/26', -4);
OK
_c0
NULL
Time taken: 0.07 seconds, Fetched: 1 row(s)
想要将 / 轉換為 - 可以使用 regexp_replace() 函數:
hive (default)> select regexp_replace('2020/02/26', '/', '-');
OK
_c0
2020-02-26
Time taken: 0.068 seconds, Fetched: 1 row(s)
三、 case when
建立表并導入資料:
hive (default)> create table if not exists emp_sex(
> name string,
> dept_id string,
> sex string)
> row format delimited fields terminated by '\t';
OK
Time taken: 0.423 seconds
hive (default)> load data local inpath '/opt/module/data/emp_sex.txt'
> into table emp_sex;
Loading data to table default.emp_sex
Table default.emp_sex stats: [numFiles=1, totalSize=78]
OK
Time taken: 0.251 seconds
查詢資料:
hive (default)> select * from emp_sex;
OK
emp_sex.name emp_sex.dept_id emp_sex.sex
悟空 A 男
大海 A 男
宋宋 B 男
鳳姐 A 女
婷姐 B 女
婷婷 B 女
Time taken: 0.068 seconds, Fetched: 6 row(s)
求出每個部門男女各多少人:
hive (default)> select dept_id,
> sum(case sex when '男' then 1 else 0 end) male_count,
> sum(case sex when '女' then 1 else 0 end) female_count
> from emp_sex
> group by dept_id;
... ...
OK
dept_id male_count female_count
A 2 1
B 1 2
Time taken: 34.979 seconds, Fetched: 2 row(s)
也可以改用if 函數:
hive (default)> select dept_id,
> sum(if(sex='男', 1, 0)) male_count,
> sum(if(sex='女', 1, 0)) female_count
> from emp_sex
> group by dept_id;
OK
dept_id male_count female_count
A 2 1
B 1 2
Time taken: 57.188 seconds, Fetched: 2 row(s)
四、 行轉列
4.1 CONCAT
CONCAT(string A/col, string B/col, …):傳回輸入字元串連接配接後的結果, 支援任意個輸入字元串;
如:
hive (default)> select * from dept;
OK
dept.deptno dept.dname dept.loc
10 ACCOUNTING 1700
20 RESEARCH 1800
30 SALES 1900
40 OPERATIONS 1700
Time taken: 3.63 seconds, Fetched: 4 row(s)
hive (default)> select concat(deptno, '--', dname, '--', loc) from dept;
OK
_c0
10--ACCOUNTING--1700
20--RESEARCH--1800
30--SALES--1900
40--OPERATIONS--1700
Time taken: 0.057 seconds, Fetched: 4 row(s)
4.2 CONCAT_WS
可了解成 concat_with_separator, 用什麼分隔符來連接配接字元串。
如果分隔符是 NULL, 傳回值也将為 NULL。 這個函數會跳過分隔符參數後的任何 NULL。分隔符将被加到被連接配接的字元串之間。
hive (default)> select concat_ws(Null, 'a', 'b');
OK
_c0
NULL
Time taken: 0.186 seconds, Fetched: 1 row(s)
hive (default)> select concat_ws('=', 'a', 'b', Null, '1', '', '2', ' ', '3');
OK
_c0
a=b=1==2= =3
Time taken: 0.084 seconds, Fetched: 1 row(s)
4.3 COLLECT_SET
COLLECT_SET(col):函數隻接受基本資料類型, 它的主要作用是将某字段的值進行【去重彙總】。 産生 array 類型字段。
hive (default)> select * from dept;
OK
dept.deptno dept.dname dept.loc
10 ACCOUNTING 1700
20 RESEARCH 1800
30 SALES 1900
40 OPERATIONS 1700
Time taken: 0.236 seconds, Fetched: 4 row(s)
hive (default)> select collect_set(deptno) from dept;
... ...
OK
_c0
[10,20,30,40]
Time taken: 17.226 seconds, Fetched: 1 row(s)
hive (default)> select collect_set(loc) from dept;
... ...
OK
_c0
[1700,1800,1900]
Time taken: 19.131 seconds, Fetched: 1 row(s)
concat_ws() 和 collect_set() 連用:
hive (default)> select concat_ws('==', collect_set(dname)) from dept;
... ...
OK
_c0
ACCOUNTING==RESEARCH==SALES==OPERATIONS
Time taken: 23.323 seconds, Fetched: 1 row(s)
4.4 生産中的應用
需求:
原始資料:
name constellation blood_type
孫悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
豬八戒 白羊座 A
鳳姐 射手座 A
找出同星座、 同血型的人員, 并用 “|” 将其隔開, 如下:
射手座,A 大海|鳳姐
白羊座,A 孫悟空|豬八戒
白羊座,B 宋宋
開搞!
建立表:
hive (default)> create table person_info(
> name string,
> constellation string,
> blood_type string)
> row format delimited fields terminated by '\t';
OK
Time taken: 0.036 seconds
導入資料:
hive (default)> load data local inpath
> '/opt/module/data/constellation.txt'
> into table person_info;
Loading data to table default.person_info
Table default.person_info stats: [numFiles=1, totalSize=101]
OK
Time taken: 0.211 seconds
查詢資料:
hive (default)> select * from person_info;
OK
person_info.name person_info.constellation person_info.blood_type
孫悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
豬八戒 白羊座 A
鳳姐 射手座 A
Time taken: 0.031 seconds, Fetched: 5 row(s)
第一步: 先搞成下面的樣子:
hive (default)> select concat(constellation, ',', blood_type) constellation_blood,
> name
> from person_info;
OK
constellation_blood name
白羊座,A 孫悟空
射手座,A 大海
白羊座,B 宋宋
白羊座,A 豬八戒
射手座,A 鳳姐
Time taken: 0.055 seconds, Fetched: 5 row(s)
第二步: 将第一步的查詢作為一個嵌套語句:
hive (default)> select constellation_blood,
> concat_ws('|', collect_set(name))
> from
> (
> select concat(constellation, ',', blood_type) constellation_blood,
> name
> from person_info
> ) t1
> group by constellation_blood;
... ...
OK
constellation_blood _c1
射手座,A 大海|鳳姐
白羊座,A 孫悟空|豬八戒
白羊座,B 宋宋
Time taken: 26.626 seconds, Fetched: 3 row(s)
五、 列轉行
需求:
原始資料:
《疑犯追蹤》 懸疑,動作,科幻,劇情
《Lie to me》 懸疑,警匪,動作,心理,劇情
《戰狼 2》 戰争,動作,災難
最終結果:
将電影分類中的數組資料展開。結果如下:
《疑犯追蹤》 懸疑
《疑犯追蹤》 動作
《疑犯追蹤》 科幻
《疑犯追蹤》 劇情
《Lie to me》 懸疑
《Lie to me》 警匪
《Lie to me》 動作
《Lie to me》 心理
《Lie to me》 劇情
《戰狼 2》 戰争
《戰狼 2》 動作
《戰狼 2》 災難
開搞!
5.1 EXPLODE
EXPLODE(col)
: 炸裂。 将 hive 一列中複雜的 array 或者 map 結構拆分成多行。
建表:
hive (default)> create table movie_info(
> movie string,
> category array<string>)
> row format delimited fields terminated by '\t'
> collection items terminated by ',';
OK
Time taken: 0.081 seconds
導入資料:
hive (default)> load data local inpath
> '/opt/module/data/movie.txt'
> into table movie_info;
Loading data to table default.movie_info
Table default.movie_info stats: [numFiles=1, totalSize=134]
OK
Time taken: 0.211 seconds
查詢資料:
hive (default)> select * from movie_info;
OK
movie_info.movie movie_info.category
《疑犯追蹤》 ["懸疑","動作","科幻","劇情"]
《Lie to me》 ["懸疑","警匪","動作","心理","劇情"]
《戰狼 2》 ["戰争","動作","災難"]
Time taken: 0.072 seconds, Fetched: 3 row(s)
僅僅使用 explode 的話, 與電影對不上:
hive (default)> select explode(category) from movie_info;
OK
col
懸疑
動作
科幻
劇情
懸疑
警匪
動作
心理
劇情
戰争
動作
災難
Time taken: 0.062 seconds, Fetched: 12 row(s)
如果直接加上電影名稱字段則報錯:
hive (default)> select movie, explode(category) from movie_info;
FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions
這個時候就需要下面的函數了。
5.2 lateral view
側寫。
用法:
LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解釋:用于和 split、 explode 等 UDTF 一起使用。 它能夠将一列資料拆成多行資料。 在此基礎上可以對拆分後的資料進行聚合。
hive (default)> select movie, category_alias
> from movie_info
> lateral view explode(category) tbl_tmp as category_alias;
OK
movie category_alias
《疑犯追蹤》 懸疑
《疑犯追蹤》 動作
《疑犯追蹤》 科幻
《疑犯追蹤》 劇情
《Lie to me》 懸疑
《Lie to me》 警匪
《Lie to me》 動作
《Lie to me》 心理
《Lie to me》 劇情
《戰狼 2》 戰争
《戰狼 2》 動作
《戰狼 2》 災難
Time taken: 0.046 seconds, Fetched: 12 row(s)
5.3 額外拓展
将每個類型與用 “|” 隔開的對應的(多個)電影名稱展示出來:
hive (default)> select category_alias, concat_ws('|', collect_set(movie))
> from
> (
> select movie, category_alias
> from movie_info
> lateral view explode(category) tbl_tmp as category_alias
> ) t1
> group by category_alias;
... ...
OK
category_alias _c1
劇情 《疑犯追蹤》|《Lie to me》
動作 《疑犯追蹤》|《Lie to me》|《戰狼 2》
心理 《Lie to me》
懸疑 《疑犯追蹤》|《Lie to me》
戰争 《戰狼 2》
災難 《戰狼 2》
科幻 《疑犯追蹤》
警匪 《Lie to me》
Time taken: 42.121 seconds, Fetched: 8 row(s)