窗口可以理解为记录集合,窗口函数就是在满足某种条件的记录集合上执行的特殊函数。窗口函数也称为OLAP函数,OLAP即实时分析处理(Online Analytical Processing)。
语法:
<窗口函数> OVER ([PARTITION BY <分组列>] ORDER BY <排序列>)
(注:通过PARTITION BY分组后的记录集合称为窗口,如果不使用PARTITION BY,那么整个数据集将作为一个大的窗口。)
(注:窗口函数只能在SELECT子句中使用。)
(注:此处的ORDER BY只用来决定窗口函数按照什么样的顺序进行计算,对结果的排序顺序没有影响。)
可以使用的窗口函数有:
1,能够作为窗口函数的聚合函数:SUM,AVG,COUNT,MAX,MIN
2,专用窗口函数:RANK,DENSE_RANK,ROW_NUMBER,等等
其中:
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行
语法总结如下:
window_function (expression) OVER (
[ PARTITION BY part_list ]
[ ORDER BY order_list ]
[ { ROWS | RANGE } BETWEEN frame_start AND frame_end ] )
例子:
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 (partition by cate_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,累计计数。因为窗口函数以当前记录作为基准进行统计,因此可以计算截止到当前的累计订单金额/平均订单金额/最大订单金额/最小订单金额/订单数是多少,还可以加上指定框架来计算移动平均(moving average)。
参考: