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