Hive-SQL工作中常用函數總結及案例實戰

目錄

0 引 言

1 空字段賦值

2 時間類

3 條件判斷

4 多行轉一行(行轉列)

5 一行變多行(列轉行)

6 窗口函數

7 排名函數

8 json解析函數

9 url解析函數

10 小 結


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, explodeUDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分後的數據進行聚合

(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中常見的查詢函數及分析函數,文中所總結的函數緊緊圍繞工作中常用函數進行分析總結,並對每種函數的用法給出了案例分析,讀者可以針對每個函數的使用進行自行嘗試。如果您覺得本篇文章有用就點個贊吧

參考鏈接:

https://blog.csdn.net/qq_26937525/article/details/54925827

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章