目錄
0 引 言
本文針對hive進行數據分析時總結了工作中常用的查詢函數及分析函數,並對每種函數的用法進行總結賦予案例,每種案例都具有詳細的解釋。文章主要以實踐爲主,緊緊圍繞工作中常用的一些函數進行總結,更注重對函數的使用方法進行分析,其後的案例讀者可自行嘗試學習,具有借鑑意義。
1 空字段賦值
(1)函數說明
1)NVL函數:給值爲NULL的數據賦值,它的格式是NVL( string1, replace_with)。它的功能是如果string1爲NULL,則NVL函數返回replace_with的值,否則返回string1的值,如果兩個參數都爲NULL ,則返回NULL。
select nvl(name,-1) from test;
2)COALESCE函數: (expression_1, expression_2, ...,expression_n)依次參考各參數表達式,遇到非null值即停止並返回該值。如果所有的表達式都是空值,最終將返回一個空值。
hive> select coalesce(1,2);
OK
1
Time taken: 0.461 seconds, Fetched: 1 row(s)
hive> select coalesce(null,2);
OK
2
Time taken: 0.407 seconds, Fetched: 1 row(s)
hive> select coalesce(null,null,3);
OK
3
Time taken: 0.081 seconds, Fetched: 1 row(s)
hive> select coalesce(null,2,3);
OK
2
Time taken: 0.082 seconds, Fetched: 1 row(s)
hive> select coalesce(null,null);
OK
NULL
Time taken: 0.15 seconds, Fetched: 1 row(s)
select coalesce(name,-1) from test;
2 時間類
(1)date_format:格式化時間
hive> select date_format('2019-03-20','yyyy-MM-dd');
OK
2019-03-20
Time taken: 0.102 seconds, Fetched: 1 row(s)
(2)date_add:時間跟天數相加
hive> select date_add('2019-03-20',5);
OK
2019-03-25
Time taken: 0.084 seconds, Fetched: 1 row(s)
(3)date_sub:時間跟天數相減
hive> select date_sub('2019-03-20',5);
OK
2019-03-15
Time taken: 0.08 seconds, Fetched: 1 row(s)
(4)datediff:兩個時間相減
hive> select datediff('2020-03-20','2019-12-24');
OK
87
Time taken: 0.078 seconds, Fetched: 1 row(s)
(5)from_unixtime:將時間戳轉換成標準的時間
語法: from_unixtime(bigint unixtime,string format)
返回值: string
說明: 轉化 UNIX 時間戳(從 1970-01-01 00:00:00 UTC 到指定時間的秒數)到當前時區的時間格式,默認的format是yyyy-MM-dd HH:mm:ss,可以指定別的。
輸入:bigint的時間戳
輸出:string格式化的時間
常用的轉換方法如下:
from_unixtime(cast(substr(cast(msg_time as string),1,10) as bigint),'yyyy-MM-dd')
一般時間戳到毫秒13位的到hive中只能處理10位的到秒,因而用上述方法進行轉換。
hive> select from_unixtime(cast(substr(cast(msg_time as string),1,10) as bigint),'yyyy-MM-dd') from dwd_iot_phm_trackcir_shock limit 1;
OK
2020-01-16
Time taken: 0.203 seconds, Fetched: 1 row(s)
(6) unix_timestamp:將標準的時間(年月日時分秒的格式,格式可以指定)轉換爲時間戳
語法: unix_timestamp(string date, string format)
返回值: bigint
說明: 轉換 pattern 格式的日期到 UNIX 時間戳。如果轉化失敗,則返回NULL。默認的format是yyyy-MM-dd HH:mm:ss,可以指定別的。
輸入值:格式化時間 String
返回值:時間戳 bigint
注意:輸入時間必須是到秒級的時間,否則轉換失敗返回NULL
hive> select unix_timestamp('2020-03-18');
OK
NULL
Time taken: 0.113 seconds, Fetched: 1 row(s)
hive> select unix_timestamp('2020-03-18 13:15:20');
OK
1584508520
Time taken: 0.198 seconds, Fetched: 1 row(s)
3 條件判斷
CASE WHEN
1. 數據準備
name |
dept_id |
sex |
果子學長 |
A |
男 |
小眼睛 |
A |
男 |
宋小寶 |
B |
男
|
韋小寶 |
A |
女 |
鳳姐 |
B |
女 |
如花姐 |
B |
女 |
2. 創建表
create table emp_sex(
name string,
dept_id string,
sex string)
row format delimited fields terminated by "\t";
3.加載數據
load data local inpath '/home/centos/dan_test/data.txt' into table emp_sex;
4.需求:求出不同部門男女各多少人
5. Hql代碼如下:
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;
結果如下:
4 多行轉一行(行轉列)
(1)相關函數說明
CONCAT(string A/col, string B/col…):返回輸入字符串連接後的結果,支持任意個輸入字符串;
CONCAT_WS(separator, str1, str2,...):它是一個特殊形式的 CONCAT()。第一個參數指明剩餘參數間的分隔符。分隔符可以是與剩餘參數一樣的字符串。如果分隔符是 NULL,返回值也將爲 NULL。這個函數會跳過分隔符參數後的任何 NULL 和空字符串(會忽略NULL和"")。分隔符將被加到被連接的字符串之間。
COLLECT_SET(col):函數只接受基本數據類型,它的主要作用是將某字段的值進行去重彙總,產生array類型字段。(UDAF函數)
(2)數據準備
name |
constellation |
blood_type |
孫悟空 |
白羊座 |
A |
豬八戒 |
雙魚座 |
A |
牛魔王 |
白羊座 |
B |
小眼睛 |
白羊座 |
A |
果子學長 |
雙魚座 |
A |
(3)需求
把星座和血型一樣的人歸類到一起。結果如下:
雙魚座,A 果子學長|豬八戒
白羊座,A 孫悟空|小眼睛
白羊座,B 牛魔王
(4) 創建本地constellation.txt,導入數據
vi constellation.txt
(5) 創建hive表並導入數據
drop table if exists person_info
create table person_info(
name string,
constellation string,
blood_type string)
row format delimited fields terminated by "\t";
load data local inpath "/home/centos/dan_test/constellation.txt" into table person_info;
(6)按需求查詢
select
t1.base_info,
concat_ws('|', collect_set(t1.name)) name
from
(select
name,
concat(constellation, ",", blood_type) base_info
from
person_info) t1
group by
t1.base_info;
執行結果如下
執行中間表結果:
執行最終結果:
5 一行變多行(列轉行)
(1)函數說明
EXPLODE(col):將hive一列中複雜的array或者map結構拆分成多行。(UDTF函數)
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解釋:用於和split, explode等UDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分後的數據進行聚合。
(2)數據準備
movie |
category |
《疑犯追蹤》 |
懸疑,動作,科幻,劇情 |
《Lie to me》 |
懸疑,警匪,動作,心理,劇情 |
《戰狼2》 |
戰爭,動作,災難 |
(3)需求
將電影分類中的數組數據展開。結果如下:
《疑犯追蹤》 懸疑
《疑犯追蹤》 動作
《疑犯追蹤》 科幻
《疑犯追蹤》 劇情
《Lie to me》 懸疑
《Lie to me》 警匪
《Lie to me》 動作
《Lie to me》 心理
《Lie to me》 劇情
《戰狼2》 戰爭
《戰狼2》 動作
《戰狼2》 災難
(4)創建本地movie.txt,導入數據
[root@bigdata3 dan_test]# vi movie.txt
《疑犯追蹤》 懸疑,動作,科幻,劇情
《Lie to me》 懸疑,警匪,動作,心理,劇情
《戰狼2》 戰爭,動作,災難
(5)創建hive表並導入數據
drop table if exists movie_info
create table movie_info(
movie string,
category array<string>)
row format delimited fields terminated by "\t"
collection items terminated by ",";
load data local inpath "/home/centos/dan_test/movie.txt" into table movie_info;
(6)按需求查詢數據
select
movie,
category_name
from
movie_info lateral view explode(category) table_tmp as category_name;
結果如下:
6 窗口函數
(1)相關函數說明
OVER():指定分析函數工作的數據窗口大小,這個數據窗口大小可能會隨着行的變化而變化;(分析函數,分析的數據範圍)。當同一個select查詢中存在多個窗口函數時,他們相互之間是沒有影響的.每個窗口函數應用自己的規則.
CURRENT ROW:當前行;
n PRECEDING:往前n行數據;
n FOLLOWING:往後n行數據;
UNBOUNDED:起點,UNBOUNDED PRECEDING 表示從前面的起點, UNBOUNDED FOLLOWING表示到後面的終點;
LAG(col,n):獲取往前第n行某字段值;
LEAD(col,n):獲取往後第n行某字段值;
注意:lag()和lead()函數可以訪問結果集中的其他行而不用進行自連接。
lag函數以當前行爲標杆獲取往前的n行數據。屬於滯後訪問,所以取名爲lag
lead函數是以當前行爲標杆獲取往後的後n行數據。屬於超前訪問,所以取名爲lead(跳躍)
關於行與行之間的比較分析可以用這兩個函數,這兩個函數是對行比較時需要自關聯的簡化,分析比較方便。
NTILE(n):把有序分區中的行分發到指定數據的組中,各個組有編號,編號從1開始,對於每一行,NTILE返回此行所屬的組的編號。注意:n必須爲int類型。(分桶函數,類似於hive中的分桶策略)
first_value():取分組內排序後,截止到當前行,第一行某字段值。如果不指定ORDER BY,則默認按照記錄在文件中的偏移量進行排序,會出現錯誤的結果。(獲取數據窗口的第一行某字段值)
last_value() :取分組內排序後,截止到當前行,最後一行某字段值。如果不指定ORDER BY,則默認按照記錄在文件中的偏移量進行排序,會出現錯誤的結果。(獲取數據窗口的最後一行某字段值)
窗口函數執行順序及使用規則:
(1)先看sql的執行順序
1 from
2 on
3 join
4 where
5 group by
6 with
7 having
8 select
9 distinct
10 order by
11 limit
(2) 窗口函數執行順序:窗口函數只能在select命令中和select命令之後使用,不能在where中使用,其執行
順序是和select同級別的,位於distinct順序之前,可以把窗口函數與分析函數結合後形成的看成select中字
段一樣,也是可以取別名的,是select的一部分。
(2)數據準備:name,orderdate,cost
name,orderdate,cost
jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94
(3)需求
1)查詢在2017年4月份購買過的顧客及總人數
2)查詢顧客的購買明細及購買總額
3)上述的場景,要將cost按照日期進行累加
4)查詢顧客上次的購買時間
5)查詢前20%時間的訂單信息
(4)創建本地business.txt,導入數據
[root@bigdata3 dan_test]# vi vi business.txt
(5)創建hive表並導入數據
create table business(
name string,
orderdate string,
cost int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
load data local inpath "/home/centos/dan_test/business.txt" into table business;
(6) 按需求查詢數據
1)查詢在2017年4月份購買過的顧客及總人數
分析:
① 查詢2017年4月份購買的詳細信息
select *
from business
where substring(orderdate,1,7) = '2017-04'
② 查詢2017年4月份購買的顧客(要求名字不能重複)
select name
from business
where substring(orderdate,1,7) = '2017-04'
group by name
③ 在上一步的基礎上要求顧客後面顯示購買的人數
採用如下語句計算:
select name,count(*)
from business
where substring(orderdate,1,7) = '2017-04'
group by name
我們可以看到所求的人數其實是group by後的記錄數,mark爲4,jack爲1統計的是顧客這個月購買的次數,而不是這個月購買的總顧客數。那麼會有同學提出下面的解法:
select count(*),t.name
from (
select name
from business
where substring(orderdate,1,7) = '2017-04'
group by name
) t ;
通過子查詢的形式,求出分組後的記錄數,就是這個月購買的顧客總數,然後再顯示其名字,不幸的是執行該語句便報如下錯誤
Error while compiling statement: FAILED: SemanticException [Error 10025]: Line 1:17
Expression not in GROUP BY key 'name'
也就是說hive在查詢時使用聚合函數的時候,如果要出現其他字段,其他字段必須在group by中,否則會出現錯誤。注意:在mysql中,使用聚合函數和其他字段一起作爲查詢時不會報錯,在hive中由於語法比較嚴格會報錯。
如下hive中
mysql中:
因此在解決次來問題時hive中爲我們提供了開窗函數,開窗函數一般與分析函數一起使用,表示分析函數分析數據的範圍。如果開窗函數遇到 group by語句,那麼窗口中無其他限定時,一般把一組看成一條記錄,相當於先進行分組後,分組後這一組內整體的記錄數被作爲一條記錄。因此此題可藉助窗口函數進行分析,正確的Hql語句爲:
select name,count(*) over ()
from business
where substring(orderdate,1,7) = '2017-04'
group by name;
其執行結果如下:
2)查詢顧客的購買明細及月購買總額
分析:查詢顧客的購買明細指的是所有的信息都要被出現,月購買總額,說明數據的分析範圍是按月來計算。也就是窗口大小是按月分組,窗口分組我們採用partition by來指明按什麼分組,分組也可以按照多個字段進行分組。分析函數採用sum()函數,是對cost求總額,於是HQL語句爲:
select name
,orderdate
,cost
,sum(cost) over(partition by month(orderdate))
from business
order by name,orderdate ;
結果如下:
3)上述的場景,要將cost按照日期進行累加
select name,orderdate,cost,
sum(cost) over() as sample1,--所有行相加
sum(cost) over(partition by name) as sample2,--按name分組,組內數據相加
sum(cost) over(partition by name order by orderdate) as sample3,--按name分組,組內數據累加
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一樣,由起點到當前行的聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --當前行和前面一行做聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--當前行和前邊一行及後面一行
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --當前行及後面所有行
from business;
執行結果如下:
分析:
① sum(cost) over() as sample1 :表示對窗口內所有數據進行相加,此時over()相當於全範圍內數據,即所有行的數據
② sum(cost) over(partition by name) as sample2 表示:按name分組,組內數據相加。partition by子句表示分組(注意與group by區別開來,partition by分組的順序要晚於group by,先進行group by之後此時分組後的數據被作爲整體看成一條輸入數據),窗口函數中採用了partition by子句,那麼此時窗口的大小爲分組後的大小,sum(cost) over(partition by name就表示對分組后里面的數據進行相加。
③ sum(cost) over(partition by name order by orderdate) as sample3 :表示按name分組,組內數據累加。注意此處多了order by 子句,表示組內數據累加,其數據的分析範圍爲從起點到當前行,這一點一定要注意。相當於sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) (只不過此處默認是: rows between UNBOUNDED PRECEDING and current row)
order by子句會讓輸入的數據強制排序,Order By子句對於諸如Row_Number(),Lead(),LAG()等函數是必須
的,因爲如果數據無序,這些函數的結果就沒有任何意義。
注意點:
- 如果只使用partition by子句,未指定order by的話,我們的分析函數的作用範圍是分組內的數據.
- 使用了order by子句,未使用window子句的情況下,默認數據分析範圍是從起點到當前行,往往用來實現累加.
window子句:
- PRECEDING:往前
- FOLLOWING:往後
- CURRENT ROW:當前行
- UNBOUNDED:起點,UNBOUNDED PRECEDING 表示從前面的起點, UNBOUNDED FOLLOWING:表示到後面的終點
④ sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一樣,由起點到當前行的聚合.
⑤ sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --當前行和前面一行做聚合,此句在order by後面指明瞭window子句表明了數據分析的範圍爲rows between 1 PRECEDING and current row
前一行到當前行。
⑥ sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--當前行和前邊一行及後面一行。如當讀到第一行時候,累加數據爲:10+46=56.當讀到第二行的時候,累加數據爲:10+46+55=111。當讀到第三行的時候,累加數據爲46+55+23=124.以此類推。
⑦ sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --當前行及後面所有行。當讀到第一行時,10+46+55+23+42=176,第二行:46+55+23+42=166,第三行:55+23+42=120,以此類推。
4)查看顧客上次的購買時間
select name,orderdate,cost,
lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as time1,
lag(orderdate,2) over (partition by name order by orderdate) as time2
from business;
結果如下:
分析:
查詢顧客上次購買的時間,很明顯按顧客分組,按時間排序,但如何拿到上一條記錄呢?如果在mysql中比較複雜需要做關聯計算,但是在hive中提供了相關的函數可以用於計算。hive中通過lag()函數來獲取前n行數據(從當前行開始,往前數n行,獲取該行數據),默認是前1行數據,也就是上一條記錄值。
time1取的爲按照name進行分組,分組內升序排列,取上一行日期的值,也就是上次購買的時間.
time2取的爲按照name進行分組,分組內升序排列,從當前行開始往前數兩行,定位到該位置時的日期值,也就是上
上次購買的時間。注意當lag函數第二個參數默認爲1,第三個參數表示未設定取不到時的默認值時,用戶未指定時
默認值爲null值.
lead函數與lag函數方向相反,取向下的數據,表示下一跳.
5)查詢前20%時間的訂單信息
select * from (
select name,orderdate,cost, ntile(5) over(order by orderdate) bucket
from business
) t
where bucket = 1;
分析:
hive中分桶函數的使用:
- hive中分桶函數NTILE(n):用於將分組數據按照順序切分成n片,返回當前切片值.切片值就是桶的序號
- NTILE不支持ROWS BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)。
- 如果切片不均勻,默認增加第一個切片的分佈
注意:ntile分桶是基於一定順序分組的,也就是按照排好的序,進行平均分組,若不能平均分則優先分配較小編
號的桶,並且各個桶中能放的行數最多相差1,這種分桶不具備散列性。mod求餘分桶按照餘數決定數據去哪個桶
中,因而具有散列性,分桶後性能較好,將數據打散時候使用。兩者的應用場景不一樣,但都達到分桶的目的。
ntile更多的是求前多少的百分比,後多少的百分比時候使用。
其思想也可參考hive中建表時的分桶。
該需求表示對全局的數據進行分桶,查詢前20%=1/5說明需要分五個桶,按照時間順序由低到高進行排序,取第一個分桶中的數據。執行分桶語句計算結果如下:
select name,orderdate,cost
,ntile(5) over(order by orderdate) bucket
from business
最終需求執行結果如下:
查詢每位顧客購買金額前1/3的交易記錄
select name,orderdate,cost,
ntile(3) over() as bucket1 , --全局數據切片
ntile(3) over(partition by name) as bucket2, -- 按照name進行分組,在分組內將數據切成3份
ntile(3) over(order by cost) as bucket3,--全局按照cost升序排列,數據切成3份
ntile(3) over(partition by name order by cost ) as bucket4 --按照name分組,在分組內按照cost升序排列,數據切成3份
from business
執行結果如下:
最終的需求結果爲bucket = 1的那部分結果即是我們需要的結果
select t.name
,t.orderdate
,t.cost
,t.bucket
from (
select name,orderdate,cost,
ntile(3) over(partition by name order by cost ) as bucket
from business) t
where t.bucket = 1
執行結果如下:
6)求每位顧客當前購買日期與最開始購買日期的時間間隔
分析:
first_value():取分組內排序後,截止到當前行,第一個值。如果不指定ORDER BY,則默認按照記錄在文件中的偏移量進行排序,會出現錯誤的結果。
last_value() :取分組內排序後,截止到當前行,最後一個值。如果不指定ORDER BY,則默認按照記錄在文件中的偏移量進行排序,會出現錯誤的結果
select name,orderdate,cost,
first_value(orderdate) over(partition by name order by orderdate),
last_value(orderdate) over(partition by name order by orderdate)
from business;
結果如下:
最終結果:
select t.name,t.orderdate,t.cost
,datediff(t.last_value,t.first_value) as intervalue
from(
select name,orderdate,cost,
first_value(orderdate) over(partition by name order by orderdate) as first_value,
last_value(orderdate) over(partition by name order by orderdate) as last_value
from business
) t
結果如下:
7 排名函數
(1)函數說明
RANK() 排序相同時會重複,總數不會變。跳躍排名
DENSE_RANK() 排序相同時會重複,總數會減少。等位排名
ROW_NUMBER() 會根據順序計算(順序編號,經常使用,唯一標記一條記錄)。順序排名
(2)數據準備
name |
subject |
score |
果子學長 |
語文 |
87 |
果子學長 |
數學 |
95 |
果子學長 |
英語 |
68 |
小眼睛 |
語文 |
94 |
小眼睛 |
數學 |
56 |
小眼睛 |
英語 |
84 |
鳳姐 |
語文 |
64 |
鳳姐 |
數學 |
86 |
鳳姐 |
英語 |
84 |
如花 |
語文 |
65 |
如花 |
數學 |
85 |
如花 |
英語 |
78 |
(3)需求
計算每門學科成績排名。
(4)創建本地score.txt,導入數據
[root@bigdata3 dan_test]# vi score.txt
(5)創建hive表並導入數據
create table score(
name string,
subject string,
score int)
row format delimited fields terminated by "\t";
load data local inpath '/home/centos/dan_test/score.txt' into table score;
(6) 按需求查詢數據
select name,
subject,
score,
rank() over(partition by subject order by score desc) rk,
dense_rank() over(partition by subject order by score desc) dr,
row_number() over(partition by subject order by score desc) rn
from score;
執行結果如下:
8 json解析函數
(1)get_json_object
語法: get_json_object(string json_string, string path)
返回值: string
說明:解析json的字符串json_string,返回path指定的內容。如果輸入的json字符串無效,那麼返回NULL。
(2) json_tuple
語法: json_tuple(string json_string, col1, col2, …) ,經常和lateral view一起使用
返回值: string
說明:同時解析多個json字符串中的多個字段
(3) 數據準備
jsondata.txt
1 {"store":{"fruit":[{"weight":8,"type":"apple"}, {"weight":9,"type":"pear"}], "bicycle":{"price":19.95,"color":"red"}}, "email":"amy@only_for_json_udf_test.net", "owner":"amy"}
2 {"store":{"fruit":[{"weight":9.1,"type":"apple"}, {"weight":9.2,"type":"pear"}], "bicycle":{"price":21.01,"color":"blue"}}, "email":"[email protected]", "owner":"xiaoyanjing"}
(4)建表插入數據
drop table if exists json_data_test
create table if not exists json_data_test(
id int,
data string)
row format delimited fields terminated by '\t';
load data local inpath '/home/centos/dan_test/jsondata.txt' into table json_data_test;
(5) 需求查詢
① 獲取單層值
select get_json_object(data '$.owner') from json_data_test;
hive> select id,get_json_object(data, '$.owner') from json_data_test;
OK
1 amy
2 xiaoyanjing
② 獲取多層值
hive> select id, get_json_object(data, '$.store.bicycle.price') from json_data_test;
OK
1 19.95
2 21.01
Time taken: 0.089 seconds, Fetched: 2 row(s)
③ 獲取數組值[]及數組選項值(多層解析)
(1)獲取fruit值,可以看到返回爲數組
hive> select id, get_json_object(data, '$.store.fruit') from json_data_test;
OK
1 [{"weight":8,"type":"apple"},{"weight":9,"type":"pear"}]
2 [{"weight":9.1,"type":"apple"},{"weight":9.2,"type":"pear"}]
Time taken: 0.079 seconds, Fetched: 2 row(s)
(2)獲取數組裏面的值可以用數組索引的方式獲取
hive> select id, get_json_object(data, '$.store.fruit[0]') from json_data_test;
OK
1 {"weight":8,"type":"apple"}
2 {"weight":9.1,"type":"apple"}
Time taken: 0.136 seconds, Fetched: 2 row(s)
可以看到返回的還是json串。
(3)在步驟2的基礎上獲取weight和type的值
hive> select id, get_json_object(data, '$.store.fruit[0].weight') from json_data_test;
OK
1 8
2 9.1
Time taken: 0.13 seconds, Fetched: 2 row(s)
hive> select id, get_json_object(data, '$.store.fruit[0].type') from json_data_test;
OK
1 apple
2 apple
Time taken: 0.134 seconds, Fetched: 2 row(s)
hive>
完整版獲取:
select id
,get_json_object(data, '$.store.fruit[0].weight')
,get_json_object(data, '$.store.fruit[0].type')
,get_json_object(data, '$.store.fruit[1].weight')
,get_json_object(data, '$.store.fruit[1].type')
from json_data_test;
結果如下:
9 url解析函數
(1)函數說明
語法: parse_url(string urlString, string partToExtract , string keyToExtract)
返回值: string
說明:返回 URL 中指定的部分。 partToExtract 的有效值爲: HOST, PATH, QUERY, REF,
PROTOCOL, AUTHORITY, FILE, and USERINFO.
(2) 數據準備
1 https://blog.csdn.net/godlovedaniel/article/details/104860042
2 https://blog.csdn.net/godlovedaniel/article/details/104735170
(3) 創建表並加載數據
drop table if exists url_data_test
create table if not exists url_data_test(
id int
,data string)
row format delimited fields terminated by '\t';
load data local inpath '/home/centos/dan_test/urldata.txt' into table url_data_test;
(4)需求分析
1)獲取url協議
select id, parse_url(data, 'PROTOCOL') from url_data_test;
2) 獲取主機名
select id, parse_url(data, 'HOST') from url_data_test;
查詢結果如下:
3)獲取路徑
select id, parse_url(data, 'PATH') from url_data_test;
4)獲取所有參數的序列
select id, parse_url(data, 'QUERY') from url_data_test;
查詢結果如下:
5)獲取文件完整路徑
select id, parse_url(data, 'FILE') from url_data_test;
10 小 結
本文充分總結了hive中常見的查詢函數及分析函數,文中所總結的函數緊緊圍繞工作中常用函數進行分析總結,並對每種函數的用法給出了案例分析,讀者可以針對每個函數的使用進行自行嘗試。如果您覺得本篇文章有用就點個贊吧
參考鏈接: