团队介绍
网易乐得DBA组,负责网易乐得电商、网易邮箱、网易技术部数据库日常运维,负责数据库私有云平台的开发和维护,负责数据库及数据库中间件Cetus的开发和测试等等。
一、窗口函数的使用场景
作为IT人士,日常工作中经常会遇到类似这样的需求:
医院看病,怎样知道上次就医距现在的时间?环比如何计算?怎么样得到各部门工资排名前N名员工列表?查找各部门每人工资占部门总工资的百分比?
对于这样的需求,使用传统的SQL实现起来比较困难。这类需求都有一个共同的特点,需要在单表中满足某些条件的记录集内部做一些函数操作,不是简单的表连接,也不是简单的聚合可以实现的,通常会让写SQL的同学焦头烂额、绞尽脑汁,费了大半天时间写出来一堆长长的晦涩难懂的自连接SQL,且性能低下,难以维护。
要解决此类问题,最方便的就是使用窗口函数。
二、MySQL窗口函数简介
MySQL从8.0开始支持窗口函数,这个功能在大多商业数据库和部分开源数据库中早已支持,有的也叫分析函数。
什么叫窗口?
窗口的概念非常重要,它可以理解为记录集合,窗口函数也就是在满足某种条件的记录集合上执行的特殊函数。对于每条记录都要在此窗口内执行函数,有的函数随着记录不同,窗口大小都是固定的,这种属于静态窗口;有的函数则相反,不同的记录对应着不同的窗口,这种动态变化的窗口叫滑动窗口。
窗口函数和普通聚合函数也很容易混淆,二者区别如下:
-
聚合函数是将多条记录聚合为一条;而窗口函数是每条记录都会执行,有几条记录执行完还是几条。
-
聚合函数也可以用于窗口函数中,这个后面会举例说明。
下面是一个窗口函数的简单例子:
上面例子中,row_number()over(partition by user_no order by amount desc)这部分都属于窗口函数,它的功能是显示每个用户按照订单金额从大到小排序的序号。
按照功能划分,可以把MySQL支持的窗口函数分为如下几类:
-
序号函数:row_number() / rank() / dense_rank()
-
分布函数:percent_rank() / cume_dist()
-
前后函数:lag() / lead()
-
头尾函数:first_val() / last_val()
-
其他函数:nth_value() / nfile()
三、窗口函数如何使用
窗口函数的基本用法如下:
函数名ÿ