窗口函数是我最近在做数据分析时学到的小技巧, 下面就写一篇blog记录一下。。。
基本语法
比起熟悉的 group by 操作, 窗口函数的好处就是不会不减少原表的行数, 以及使代码变得更加优雅(bushi)。
首先来看看 mysql 窗口函数的语法格式:1
2函数名([expr]) over 子句
over 是关键字,用来指定函数执行的窗口范围
而子句则有三类:
partition子句:窗口按照那些字段进行分组,窗口函数在不同的分组上分别执行。order by子句:按照哪些字段进行排序,窗口函数将按照排序后的记录顺序进行编号。frame子句:定义子集的规则,通常用来作为滑动窗口使用。
比如要根据班级进行分组并按年纪进行排序, 使用rank函数计算排名:1
select *,rank() over (partition by classname order by grade desc) as ranking from class;
比如说要操作 Logs 表连续出现次数至少3次的数字:1
2
3
4
5
6
7
8
9with
p as (
select id, num,
lead(num, 1) over (order by id) as num1, -- 选求num列当前行后面第1个数字
lead(num, 2) over (order by id) as num2 -- 选求num列当前行后面第2个数字
from Logs)
select distinct p.num as ConsecutiveNums
from p where p.num=p.num1 and p.num1=p.num2;
思路是使用 with 语句创建一个运用完窗口函数的临时表 p:1
2
3
4
5
6
7
8
9| id | num | num1 | num2 |
| -- | --- | ---- | ---- |
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 2 |
| 3 | 1 | 2 | 1 |
| 4 | 2 | 1 | 2 |
| 5 | 1 | 2 | 2 |
| 6 | 2 | 2 | null |
| 7 | 2 | null | null |
当然 mysql 支持的窗口函数还有很多, 需要用到的时候就直接查 api 啦。。。