hive窗口函數實戰(2)

1.什麼是窗口函數

在明白窗口函數的用途之前,我們先稍微提一下聚合函數,比如sum, count等常用的聚合函數,作用是將一列中多行的值合併爲一行。與之對應的是,窗口函數完成的功能是本行內運算,從而多行的運算結果,即每一行的結果對應的多行的結果。一般窗口函數的語法爲

function() over (partition by column1, column2 order by column3)

2.窗口函數的類型

1.聚合型,像sum,count,avg等操作。
2.分析型,像rank, row_number, dense_rank等常見的排序窗口函數。
3.取值型窗口函數, lag, lead等。

3.例子

3.1 取分組以後的最大值

select * from 
( 
select *,ROW_NUMBER() OVER(PARTITION BY idtype ORDER BY id DESC) as num 
from tablexxx 
) t 
where t.num = 1

上面的代碼,先按照idtype進行分組partition,然後取每個分組中最大的那個id。

3.2 按某個字段分組以後將另外的字段聚合

select collect_set(b) over(distribute by a order by c) from tablexxx

按字段a分組,按字段c排序,然後將字段b聚合在一起。如果是collect_list表示字段不去重,collect_set表示字段去重。

如果需要對字段b裏的內容進行排序,可以用sort_array。

select sort_array(collect_set(b) over(distribute by a)) from tablexxx

3.3 與group by做對比

假設有以下數據

zs	classA	80
ls	classB	83
ww	classA	88
xl	classC	92
wl	classB	79
lu	classC	85

字段名分別爲name, grade, score,表名爲table_test_data。現在想獲取每個grade的最大score,我們可以這麼寫

select grade, max(score) from table_test_data where date=20200409 group by grade

當然,我們還可以用窗口函數寫

select grade, score from (select *, row_number() over (partition by grade order by score desc) as num from browser.table_test_data where date=20200409)t where t.num = 1;

上面兩個語句跑出來的結果相同

grade	score
classA	88
classB	83
classC	92

當然直接用group by比窗口函數要簡單很多。但是如果我們還想獲取name咋辦?
這個時候group by就無能爲力了,窗口函數可以。

select name, grade, score from (select *, row_number() over (partition by grade order by score desc) as num from browser.table_test_dta where date=20200409)t where t.num = 1;

結果爲

name	grade	score
ww	classA	88
ls	classB	83
xl	classC	92

總結一下就是
如果要select出不在group by語句中的字段,而且該字段不在聚合函數裏,則應該使用row_number() over(partition by),如果需要select的字段全在group by中,則可以直接使用group by語句。

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