SQL---窗口函數(window function)


窗口可以理解為記錄集合,窗口函數就是在滿足某種條件的記錄集合上執行的特殊函數。窗口函數也稱為OLAP函數,OLAP即實時分析處理(Online Analytical Processing)。

 

語法:

window_function (expression) OVER (
   [ PARTITION BY part_list ]
   [ ORDER BY order_list ]
   [ { ROWS | RANGE } BETWEEN frame_start AND frame_end ] )

(注:通過PARTITION BY分組后的記錄集合稱為窗口,如果不使用PARTITION BY,那么整個數據集將作為一個大的窗口。)

(注:PARTITION BY 子句不具備GROUP BY 子句的匯總功能,因此使用窗口函數並不會減少原表中記錄的行數。)

(注:窗口函數只能在SELECT子句中使用。)

(注:此處的ORDER BY只用來決定窗口函數按照什么樣的順序進行計算,對結果的排序順序沒有影響。)

 

可以使用的窗口函數有:

1,聚合函數:SUM,AVG,COUNT,MAX,MIN

2,專用的窗口函數:RANK,DENSE_RANK,ROW_NUMBER等排序函數;LEAD,LAG等差值函數

 

專用窗口函數完整列表(摘自:https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html):

Name Description
CUME_DIST() Cumulative distribution value
DENSE_RANK() Rank of current row within its partition, without gaps
FIRST_VALUE() Value of argument from first row of window frame
LAG() Value of argument from row lagging current row within partition
LAST_VALUE() Value of argument from last row of window frame
LEAD() Value of argument from row leading current row within partition
NTH_VALUE() Value of argument from N-th row of window frame
NTILE() Bucket number of current row within its partition.
PERCENT_RANK() Percentage rank value
RANK() Rank of current row within its partition, with gaps
ROW_NUMBER() Number of current row within its partition

 

其中:

RANK():計算排序(如果存在相同位次的記錄,則會跳過之后的位次,比如:1,2,2,4)

DENSE_RANK():計算排序(即使存在相同位次的記錄,也不會跳過之后的位次,比如:1,2,2,3)

ROW_NUMBER():賦予連續且唯一的位次,比如:1,2,3,4

 

此外,除了partition子句和order by子句,還可以加上frame子句。frame是當前分區的一個子集,frame子句用來定義子集的規則,其通常作為滑動窗口使用。(即指定框架:對窗口進行更詳細地指定。)例如:

ROW 2 PRECEDING:前2行

ROW 5 FOLLOWING:后5行

ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING:前1行到后1行

 

在有order by的情況下,frame的默認值是:ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW (之前所有行到當前行)。

 

例子:

SELECT item_id, cate_id, RANK() OVER (PARTITION BY cate_id ORDER BY price) as rank FROM item_list;
SELECT item_id, cate_id, SUM(price) OVER (ORDER BY item_id) as rank FROM item_list;
SELECT item_id, cate_id, AVG(price) OVER (ORDER BY price ROWS BETWEEN 1 PRECEDING and 1 FOLLOWING) AS rank FROM item_list;

 

為什么要用窗口函數?

1,在組內進行排名。比如統計各個部門工資前3位的員工名單。

2,累計計數。因為窗口函數以當前記錄作為基准進行統計,因此可以計算截止到當前的累計訂單金額是多少(running total),還可以加上指定框架來計算移動平均(moving average)。

3,計算前后差值。比如計算各用戶每天使用APP的時間。

 

參考:

https://ericfu.me/sql-window-function/

 


免責聲明!

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



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