窗口函數是用於分析用的一類函數,要理解窗口函數要先從聚合函數說起。
- 聚合函數是將某列中多行的值合併爲一行,比如sum、count等。
- 窗口函數則可以在本行內做運算,得到多行的結果,即每一行對應一行的值。
語法概括:
Function() Over (Partition By Column1,Column2,Order By Column3)
FIRST_VALUE(col)
,LAST_VALUE(col)
可以返回窗口幀中第一條或最後一條記錄的指定字段值;
LEAD(col, n)
,LAG(col, n)
返回當前記錄的上
n
條或下n
條記錄的字段值;
RANK()
,ROW_NUMBER()
會爲幀內的每一行返回一個序數,區別在於存在字段值相等的記錄時,
RANK()
會返回相同的序數;
COUNT(),
SUM(col)
,MIN(col)
和一般的聚合操作相同
窗口函數又分爲以下三類: 聚合型窗口函數 分析型窗口函數 取值型窗口函數
- 聚合型窗口函數:
SUM(), MIN(),MAX(),AVG(),COUNT()這些常見的聚合函數。
- 分析型窗口函數:
RANK(),ROW_NUMBER(),DENSE_RANK()等常見的排序用的窗口函數
- 取值型窗口函數:
- LAG是遲滯的意思,也就是對某一列進行往後錯行
- LEAD是LAG的反義詞,也就是對某一列進行提前幾行
- FIRST_VALUE是對該列到目前爲止的首個值
- LAST_VALUE是到目前行爲止的最後一個值
基本用法:
(ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN CURRENT ROW AND (CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN [num] FOLLOWING AND (UNBOUNDED | [num]) FOLLOWING
解釋:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
表示選擇分區起始記錄到當前記錄的所有行
SUM(close) RANGE BETWEEN 100 PRECEDING AND 200 FOLLOWING
則通過 字段差值 來進行選擇,如當前行的
close
字段值是200
,那麼這個窗口幀的定義就會選擇分區中close
字段值落在100
至400
區間的記錄
窗口函數基本原理:
窗口分區: PARTITION
語句會按照一個或多個指定字段,將查詢結果集拆分到不同的 窗口分區 中,並可按照一定規則排序
窗口幀: 用於從分區中選擇指定的多條記錄,供窗口函數處理。Hive 提供了兩種定義窗口幀的形式:ROWS
和 RANGE
。兩種類型都需要配置上界和下界
窗口函數: 會基於當前窗口幀的記錄計算結果
group by 與 partition by的區別:
帶上group by的hive sql語句只能顯示與分組聚合相關的字段
而帶上over(partition by ……)的hive sql語句能顯示所有字段
hive中三個排序函數rank、row_number、dense_rank三者的區別:
- rank()函數 此排序方法進行排序時,相同的排序是一樣的,而且下一個不同值是跳着排序的。
- row_number()函數 此方法不管排名是否有相同的,都按照順序1,2,3…..n
- dense_rank()函數 此方法對於排名相同的名次一樣,且後面名次不跳躍
示例:
1月100,2月200,3月100,4月200.統計如下效果:1月100,2月300,3月500,4月600.【就是每月統計一次前面所有的月的總額】
select month,amount,sum(amount) over(order by month asc) from expense;
select t.* ,(select sum(amount) from expense where month <= t.month) from expense t;
參考:
http://shzhangji.com/cnblogs/2017/09/05/hive-window-and-analytical-functions/