開窗函數是在滿足某種條件的記錄集合上執行的特殊函數。對于每條記錄都要在此窗口內執行函數,有 的函數隨著記錄不同,窗口大小都是固定的,這種屬于靜態窗口;有的函數則相反,不同的記錄對應著 不同的窗口,這種動態變化的窗口叫滑動窗口。開窗函數的本質還是聚合運算,只不過它更具靈活性, 它對數據的每一行,都使用與該行相關的行進行計算并返回計算結果。
語法:開窗函數名([<字段名>]) over([partition by <分組字段>] [order by <排序字段> [desc]] [< 滑動窗口>])
開窗函數的一個概念是當前行,當前行屬于某個窗口,窗口由over關鍵字來指定函數執行的窗口范圍, 如果后面括號中什么都不寫,則意味著窗口包含滿足where條件的所有行,開窗函數基于所有行進行計 算;如果不為空,則有三個參數來設置窗口:
partition by子句:按照指定字段進行分區,兩個分區由邊界分隔,開窗函數在不同的分區內分別 執行,在跨越分區邊界時重新初始化。
order by子句:按照指定字段進行排序,開窗函數將按照排序后的記錄順序進行編號??梢院?partition by子句配合使用,也可以單獨使用。
frame子句:當前分區的一個子集,用來定義子集的規則,通常用來作為滑動窗口使用。
對于滑動窗口的范圍指定,通常使用 between frame_start and frame_end 語法來表示行范圍, frame_start和frame_end可以支持如下關鍵字,來確定不同的動態行記錄:
current row 邊界是當前行,一般和其他范圍關鍵字一起使用
unbounded preceding 邊界是分區中的第一行
unbounded following 邊界是分區中的最后一行
expr preceding 邊界是當前行減去expr的值
expr following 邊界是當前行加上expr的值
比如,下面都是合法的范圍:
rows between 1 preceding and 1 following 窗口范圍是分區中的當前行、前一行、后一行一共三 行記錄。
rows between 1 preceding and current row 窗口范圍是分區中的前一行、當前行一共兩行記錄。
rows between current row and 1 following 窗口范圍是分區中的當前行、后一行一共兩行記錄。
rows unbounded preceding 窗口范圍是分區中的第一行到當前行。
rows between unbounded preceding and current row 窗口范圍是分區中的第一行到當前行。
rows between current row and unbounded following 窗口范圍是分區中的當前行到最后一行。
rows between unbounded preceding and unbounded following 窗口范圍是當前分區中所有行。
動態窗口函數:fifirst_value() / last_value()/nth_value()/聚合函數用于開窗
如沒有指定排序和滑動窗口范圍,默認計算的是分區內的所有記錄。
指定分區和排序后,如沒有指定滑動窗口范圍,默認計算的是分區內的第一行到當前行。
靜態窗口函數:row_number() / rank() / dense_rank()/percent_rank() / cume_dist()/lag() / lead()/ntile()
不管是否指定滑動窗口范圍,窗口都是固定的,所以指定的滑動窗口范圍無效。
開窗函數和普通聚合函數的區別: 聚合函數是將多條記錄聚合為一條;而開窗函數是每條記錄都會執行,有幾條記錄執行完還是幾 條。
聚合函數也可以用于開窗函數中。








暫無數據