一.窗口函数
首先看窗口函数的使用格式:
<窗口函数> OVER ([PARTITION BY <列清单>] ORDER BY <排序用列清单>
上面中熟悉的部分是 order by 这个排序命令,而 partition by 使用来 分组的,最为陌生的就是窗口函数。
窗口函数可以分为两类:
- 能够作为窗口函数的聚合函数( SUM、 AVG、 COUNT、 MAX、 MIN)
- RANK、 DENSE_RANK、 ROW_NUMBER 等专用窗口函数
来看一个例子:rank 是用来计算记录排序的函数,对于之前使用过的 Product 表中的 8 件商品,让我们根据不
同的商品种类(product_type),按照销售单价(sale_price)从低到高的顺序排序, 也就是每种类排序,这点有点类似于每个班级都排前三名。
select product_name, product_type, sale_price,
rank() over (partition by product_type order by sale_price) as ranking
from product;
需要说明的是窗口函数在 MySQL8中可以使用,但是在5版本中并不可以用。
窗口函数的灵魂在于 over 后面接的。
partition by 类似于 group by ,而order by 就是进行排序。排序也可以用desc来实现反向排序
但是, PARTITION BY 子句并不具备GROUP BY 子句的汇总功能,只是用来排序的。通过 PARTITION BY 分组后的记录集合称为窗口。此处的窗口并非“窗户”的意思,而是代表范围。这也是“窗口函数”名称的由来。
select product_name, product_type, sale_price,
rank() over (order by sale_price desc) as ranking
from product;
但如果我们把order by 去除的话,只用 partition by 的话,看看效果:
select product_name, product_type, sale_price,
rank() over (partition by product_type
-- order by sale_price desc
) as ranking
from product;
我们发现没有使用 order by 的话,那就是说所有的行之间并不存在顺序,那就所有的行都是第一行。
- 排序函数的拓展,dense_rank,row_number,看上面的例子,rank(),就是一般的成绩表的形式,1,1,3这种形式。而dense_rank,则是 1,1,2这种形式的排序,而 row_number 故名思意就是1,2,3 每行拥有唯一的顺序。
select sale_price,
rank() over (order by sale_price) as ranking,
dense_rank() over