加入收藏 | 设为首页 | 会员中心 | 我要投稿 威海站长网 (https://www.0631zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

MySQL窗口函数

发布时间:2022-12-08 13:31:31 所属栏目:MsSql教程 来源:转载
导读: 目录:1、窗口函数简介2、语法简介
语法:
函数名([参数]) over(partition by [分组字段] order by [排序字段] asc/desc rows/range between 起始位置 and 结束位置)
函数解读:
函数分为两

目录:1、窗口函数简介2、语法简介

语法:

函数名([参数]) over(partition by [分组字段] order by [排序字段] asc/desc rows/range between 起始位置 and 结束位置)

函数解读:

函数分为两个部分

第一部分是函数名称,开窗函数的数量较少,只有11个窗口函数+聚合函数(所有聚合函数都可以用作开窗函数),根据函数性质,有的要写参数,有的不需要写参数;

第二部分是over语句,over()是必须要写的,里面有三个参数,都是非必须参数,根据需求选写:

1.第一个参数是 partition by +分组字段,将数据根据此字段分成多份,如果不加partition by参数,那会把整个数据当做一个窗口。

2.第二个参数是 order by +排序字段,每个窗口的数据要不要进行排序。

3.第三个参数 rows/range between 起始位置 and 结束位置,这个参数仅针对滑动窗口函数有用,是在当前窗口下分出更小的子窗口。

其中起始位置和结束位置可写:

3、具体案例

1、创建一张班级表:mysql> create table class(id int,classname int,grade int);

2、插入数据:mysql> insert into class values(1,1,86),(2,1,95),(3,2,89),(4,1,83),(5,2,86),(6,3,92),(7,3,86),(8,1,88);

mssql 函数_周末作业b 正弦函数 与弦函数 正切函数_mssql

基础数据示例1:将每个班级中的成绩进行排名

mysql> select *,rank() over (partition by classname order by grade desc) as ranking from class;

mssql_mssql 函数_周末作业b 正弦函数 与弦函数 正切函数

已按照班级中的成绩进行排名

(如果我们不用窗口函数,直接用group by分组,则会改变行数;partition by分组的话行数不会改变。)

特点:

1、不减少原表的行数

2、同时具有分组和排序的功能

示例2:对比窗口函数rank()、dense_rank()、row_number()的区别

mysql> select *,rank() over (order by grade desc) as ranking, dense_rank() over (order by grade desc) as dense_ranking, row_number() over (order by grade desc) as row_num from class;

mssql 函数_周末作业b 正弦函数 与弦函数 正切函数_mssql

代码解读:

rank()是排名函数mssql 函数,不需要参数,因为rank函数没有参数,但需要指定按照那个字段进行排名,所以使用rank函数必须用order by参数;

over语句里面没有partition by参数,也就是整个数据视为一个窗口;

当出现名次并列时,我们使用denserank()函数就可以让下一个人的名次是连续的。

row_number连续排名

示例3:聚合窗口函数

mysql> select *,sum(grade) over (order by id) as current_sum,

-> avg(grade) over (order by id) as current_avg,

-> count(grade) over (order by id) as current_count,

-> max(grade) over (order by id) as current_max,

-> min(grade) over (order by id) as current_min

-> from class;

mssql_mssql 函数_周末作业b 正弦函数 与弦函数 正切函数

示例4:经典top N问题

所有学生中取成绩排名前三的学生:

mysql> select a.classname,a.id,a.grade,a.rownum from (select id,classname,grade,row_number() over (order by grade desc) as rownum from class) as a inner join class as b on a.id=b.id where a.rownum<=3 order by a.rownum ;
+-----------+------+-------+--------+
| classname | id   | grade | rownum |
+-----------+------+-------+--------+
|         1 |    2 |    95 |      1 |
|         3 |    6 |    92 |      2 |
|         2 |    3 |    89 |      3 |
+-----------+------+-------+--------+
3 rows in set (0.00 sec)

每门课程中取成绩排名前2的学生:

也就是每门课程中都要取出两名学生

mysql> select a.classname,a.id,a.grade,a.rownum from (select id,classname,grade,row_number() over (partition by classname order by grade desc) as rownum from class) as a inner join class as b on a.id=b.id where a.rownum<=2 order by a.classname ;
+-----------+------+-------+--------+
| classname | id   | grade | rownum |
+-----------+------+-------+--------+
|         1 |    2 |    95 |      1 |
|         1 |    8 |    88 |      2 |
|         2 |    3 |    89 |      1 |
|         2 |    5 |    86 |      2 |
|         3 |    6 |    92 |      1 |
|         3 |    7 |    86 |      2 |
+-----------+------+-------+--------+
6 rows in set (0.00 sec)

示例5:在每个组里进行比较

用窗口函数方法实现:

mysql> select * from (select a.*,avg(a.grade) over (partition by classname) as avg from class a inner join class x on x.id=a.id) q where q.grade >q.avg;
+------+-----------+-------+---------+
| id   | classname | grade | avg     |
+------+-----------+-------+---------+
|    2 |         1 |    95 | 88.0000 |
|    3 |         2 |    89 | 87.5000 |
|    6 |         3 |    92 | 89.0000 |
+------+-----------+-------+---------+
3 rows in set (0.00 sec)

用子查询方法实现:

mysql> select * from class a where grade > ( select avg(grade) from class b where b.classname=a.classname);

mssql_周末作业b 正弦函数 与弦函数 正切函数_mssql 函数

+------+-----------+-------+ | id | classname | grade | +------+-----------+-------+ | 2 | 1 | 95 | | 3 | 2 | 89 | | 6 | 3 | 92 | +------+-----------+-------+ 3 rows in set (0.00 sec)

示例6:窗口函数的移动

用rows和preceding这两个关键字是之前多少行的意思,也就是自身结果的之前两行的平均,一共三行做聚合函数

mysql> select *,avg(grade) over (order by id rows 2 preceding) as current_avg from class;
+------+-----------+-------+-------------+
| id   | classname | grade | current_avg |
+------+-----------+-------+-------------+
|    1 |         1 |    86 |     86.0000 |
|    2 |         1 |    95 |     90.5000 |
|    3 |         2 |    89 |     90.0000 |
|    4 |         1 |    83 |     89.0000 |
|    5 |         2 |    86 |     86.0000 |
|    6 |         3 |    92 |     87.0000 |
|    7 |         3 |    86 |     88.0000 |
|    8 |         1 |    88 |     88.6667 |
+------+-----------+-------+-------------+
8 rows in set (0.00 sec)

自身加上前两行求和:

mysql> select *,sum(grade) over (order by id rows 2 preceding) as current_avg fro
m class;
+------+-----------+-------+-------------+
| id   | classname | grade | current_avg |
+------+-----------+-------+-------------+
|    1 |         1 |    86 |          86 |
|    2 |         1 |    95 |         181 |
|    3 |         2 |    89 |         270 |
|    4 |         1 |    83 |         267 |
|    5 |         2 |    86 |         258 |
|    6 |         3 |    92 |         261 |
|    7 |         3 |    86 |         264 |
|    8 |         1 |    88 |         266 |
+------+-----------+-------+-------------+
8 rows in set (0.00 sec)

(编辑:威海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!