Hive窗口函數案例詳解


語法:

分析函數 over(partition by 列名 order by 列名 rows between 開始位置 and 結束位置)

常用分析函數:

  • 聚合類
    avg()、sum()、max()、min()

  • 排名類
    row_number() 按照值排序時產生一個自增編號,不會重復
    rank() 按照值排序時產生一個自增編號,值相等時會重復,會產生空位
    dense_rank() 按照值排序時產生一個自增編號,值相等時會重復,不會產生空位

  • 其他類
    lag(列名,往前的行數,[行數為null時的默認值,不指定為null])
    lead(列名,往后的行數,[行數為null時的默認值,不指定為null])
    ntile(n) 把有序分區中的行分發到指定數據的組中,各個組有編號,編號從1開始,對於每一行,ntile返回此行所屬的組的編號

注意點:

  • over()函數中的分區、排序、指定窗口范圍可組合使用也可以不指定,根據不同的業務需求結合使用
  • over()函數中如果不指定分區,窗口大小是針對查詢產生的所有數據,如果指定了分區,窗口大小是針對每個分區的數據

over()函數中的窗口范圍說明:

current row:當前行

unbounded:起點,unbounded preceding 表示從前面的起點, unbounded following表示到后面的終點

n preceding :往前n行數據

n following:往后n行數據

實戰案例1:

原始數據(用戶購買明細數據)

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


建表加載數據
vi business.txt

create table business
(
name string, 
orderdate string,
cost int
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

load data local inpath "/opt/module/data/business.txt" into table business;

需求

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

分析:按照日期過濾、分組count求總人數(分組為什么不是用group by?自己思考)

select 
name,
orderdate,
cost,
count(*) over() total_people
from 
business
where date_format(orderdate,'yyyy-MM')='2017-04';

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

分析:按照顧客分組、sum購買金額

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

(3)上述的場景,要將cost按照日期進行累加

分析:按照顧客分組、日期升序排序、組內每條數據將之前的金額累加

select 
name,
orderdate,
cost,
sum(cost) over(partition by name order by orderdate rows between unbounded preceding and current row) cumulative_amount
from 
business;

(4)查詢顧客上次的購買時間

分析:查詢出明細數據同時獲取上一條數據的購買時間(肯定需要按照顧客分組、時間升序排序)

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

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

分析:按照日期升序排序、取前20%的數據

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

實戰案例2:

原始數據(學生成績信息)

name	subject	score
孫悟空	語文	87
孫悟空	數學	95
孫悟空	英語	68
大海	語文	94
大海	數學	56
大海	英語	84
宋宋	語文	64
宋宋	數學	86
宋宋	英語	84
婷婷	語文	65
婷婷	數學	85
婷婷	英語	78


建表加載數據
vi score.txt

create table score
(
name string,
subject string, 
score int
) row format delimited fields terminated by "\t";

load data local inpath '/opt/module/data/score.txt' into table score;

需求:

(1)每門學科學生成績排名(是否並列排名、空位排名三種實現)

分析:學科分組、成績降序排序、按照成績排名

select 
name,
subject,
score,
rank() over(partition by subject order by score desc) rp,
dense_rank() over(partition by subject order by score desc) drp,
row_number() over(partition by subject order by score desc) rmp
from 
score;

(2)每門學科成績排名top n的學生

select 
*
from 
(
select 
name,
subject,
score,
row_number() over(partition by subject order by score desc) rmp
from score
) t
where t.rmp<=3;


免責聲明!

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



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