Hive(8)-常用查詢函數


一. 空字段賦值

1. 函數說明

NVL:給值為NULL的數據賦值,它的格式是NVL( value,default_value)。它的功能是如果value為NULL,則NVL函數返回default_value的值,否則返回value的值,如果兩個參數都為NULL ,則返回NULL。

2. 案例

-- 如果員工的comm為NULL,則用-1代替
select comm,nvl(comm, -1) from emp;
-- 如果員工的comm為NULL,則用領導id代替
select comm, nvl(comm,mgr) from emp;

 

二. case when

1. 函數說明

2. 案例

-- 求出不同部門男女各多少人
select dept_id,
sum(case sex when '' then 1 else 0 end) male_sum,
sum(case sex when '' then 1 else 0 end) female_sum
from emp_sex
group by dept_id;

 

三. 行轉列(concat)

1. 函數說明

CONCAT(string A/col, string B/col…):返回輸入字符串連接后的結果,支持任意個輸入字符串;

CONCAT_WS(separator, str1, str2,...):它是一個特殊形式的 CONCAT()。第一個參數是剩余參數間的分隔符。分隔符可以是與剩余參數一樣的字符串。如果分隔符是 NULL,返回值也將為 NULL。這個函數會跳過分隔符參數后的任何 NULL 和空字符串。分隔符將被加到被連接的字符串之間;

COLLECT_SET(col):函數只接受基本數據類型,它的主要作用是將某字段的值進行去重匯總,產生array類型字段。

 2.案例

將血型和星座一樣的歸類到一起

select tmp_t.base, concat_ws("|",collect_set(tmp_t.name)) name 
from(
select concat(constellation,",",blood_type) base, name from person_info
) tmp_t
group by tmp_t.base;

 

 

四. 列轉行(explode)

1.函數說明

EXPLODE(col):將hive一列中復雜的array或者map結構拆分成多行。

LATERAL VIEW : 

用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias

解釋:用於和split, explode等UDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分后的數據進行聚合。

2.案例

將電影分類中的數組數據展開

select movie, cat_name
from
movie_info lateral view explode(category) exp_tbl as cat_name;

 

五. 窗口函數(開窗函數)

1. 語法

UDAF() over (PARTITION By col1,col2 order by col3 窗口子句(rows between .. and ..)) AS 列別名

注意:PARTITION By后可跟多個字段,order By只跟一個字段。

2. 函數說明

over()決定了聚合函數的聚合范圍,默認對整個窗口中的數據進行聚合,聚合函數對每一條數據調用一次。

partition by子句:使用Partiton by子句對數據進行分區,可以用paritition by對區內的進行聚合。

order by子句作用:對分區中的數據進行排序;確定聚合哪些行(默認從起點到當前行的聚合)

窗口子句
CURRENT ROW:當前行
n PRECEDING:往前n行數據
n FOLLOWING:往后n行數據
UNBOUNDED:起點,UNBOUNDED PRECEDING 表示從前面的起點, UNBOUNDED FOLLOWING表示到后面的終點

LAG(col,n,default_val):往前第n行數據

LEAD(col,n, default_val):往后第n行數據

NTILE(n):把有序分區中的行分發到指定數據的組中,各個組有編號,編號從1開始,對於每一行,NTILE返回此行所屬的組的編號。注意:n必須為int類型。

 

tips:

通過使用partition by子句將數據進行了分區。如果想要對窗口進行更細的動態划分,就要引入窗口子句。

order by必須跟在partition by后;Rows必須跟在Order by子;(partition by .. order by)可替換為(distribute by .. sort by ..)

什么時候用開窗函數?
開窗函數常結合聚合函數使用,一般來講聚合后的行數要少於聚合前的行數,但是有時我們既想顯示聚集前的數據,
又要顯示聚集后的數據,這時我們便引入了窗口函數.

3.案例

 

1). 查詢在2017年4月份購買過的顧客及總人數

select name, count(1) over()
from business
where orderdate like "2017-04-%"
group by name;

 

2). 查詢顧客的購買明細及月購買總額

select name, orderdate, cost, sum(cost) over(partition by month(orderdate)) from business;

 

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;

 

4). 查看顧客上次的購買時間

select name,orderdate,cost, 
lag(orderdate,1,'first_buy') over(partition by name order by orderdate ) 
from business;

 

5). 查詢前20%時間的訂單信息

select * from (
    select name,orderdate,cost, ntile(5) over(order by orderdate) sorted
    from business
) t
where sorted = 1;

 

六. Rank

1.函數說明

RANK() 排序相同時會重復,總數不會變

DENSE_RANK() 排序相同時會重復,總數會減少

ROW_NUMBER() 會根據順序計算

2. 案例

計算每門學科成績排名

select name, subject, score, 
rank() over(partition by subject order by score desc) rk,
dense_rank() over(partition by subject order by score desc) drk,
row_number() over(partition by subject order by score desc) r_number
from score;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM