2020-04-01-(3)

排名问题

Create table If Not Exists Scores (Id int, Score DECIMAL(3,2))
Truncate table Scores
insert into Scores (Id, Score) values ('1', '3.5')
insert into Scores (Id, Score) values ('2', '3.65')
insert into Scores (Id, Score) values ('3', '4.0')
insert into Scores (Id, Score) values ('4', '3.85')
insert into Scores (Id, Score) values ('5', '4.0')
insert into Scores (Id, Score) values ('6', '3.65')
+----+-------+       
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+
#返回 按分数从高到低排列
+-------+------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+

窗口函数

也叫OLAP(Online Analytical Processing, 联机分析处理),可以对数据库数据进行实时分析处理

排名问题:每个部门按业绩来排名
topN问题:找出每个部门排名前N的员工进行奖励

语法

<窗口函数> over (partition by <用于分组的列名>
                order by <用于排序的列名>)

<窗口函数>:两种

  1. 专用窗口函数: rank, dense_rank, row_number
  2. 聚合函数:sum, avg, count, max, min

因为窗口函数是对where或者group by子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中

group by分组汇总后改变了表的行数,一行只有一个类别。而partiition by和rank函数不会减少原表中的行数

窗口表示范围,能够

  1. 同时具有分组和排序的功能
  2. 不减少原表的行数

rank, dense_rank, row_number区别

select *,
   rank() over (order by 成绩 desc) as ranking,
   dense_rank() over (order by 成绩 desc) as dese_rank,
   row_number() over (order by 成绩 desc) as row_num
from 班级表

输出:


image.png

rank:并列排名,不占用下一名次位置 【1,2,3,4,4,4,7】
dense_rank: (密集排名)并列排名,不占用下一名次位置【1,2,3,4,4,4,5】
row_number:正常排名【1,2,3,4,5,6,7】

三个专用窗口函数中,函数后面的括号不需要任何参数,保持()空着就可以

聚合函数为窗口函数

select *,
   sum(成绩) over (order by 学号) as current_sum,
   avg(成绩) over (order by 学号) as current_avg,
   count(成绩) over (order by 学号) as current_count,
   max(成绩) over (order by 学号) as current_max,
   min(成绩) over (order by 学号) as current_min
from 班级表

输出:


image.png

聚合函数作为窗口函数,可以在每一行的数据里直观的看到,截止到本行数据,统计数据是多少(最大值、最小值等)。同时可以看出每一行数据,对整体统计数据的影响。

partition子句可是省略,省略就是不指定分组

https://zhuanlan.zhihu.com/p/92654574

你可能感兴趣的:(2020-04-01-(3))