目录
一、小案例:
1.1测试数据如下:
1.2使用over(partition by)函数实现小案例中的SQL
二、知识扩展
2.1 over(partition by)函数的写法
2.2 与over(partition by)函数结合的函数的介绍
2.2.1 rank() 与over(partition by ... order by ...)组合函数
2.2.2 row_number() 与over(partition by ... order by ...)组合函数
2.2.3 关于rank() 和row_number()的总结
school表中有①id 序号②class 班级 ③score成绩 三个字段, 使用oracle实现按照班级分区,然后取班级中的第一名。
--创建学校表school
create table school(
id varchar2(10) primary key, --序号
class varchar2(10), --班级
score NUMBER --分数
);
--插入几条数据
insert into school (id, CLASS, SROCE) values ('1', '一班', 93);
insert into school (id, CLASS, SROCE) values ('2', '一班', 93);
insert into school (id, CLASS, SROCE) values ('3', '一班', 92);
insert into school (id, CLASS, SROCE) values ('4', '一班', 81);
insert into school (id, CLASS, SROCE) values ('5', '二班', 99);
insert into school (id, CLASS, SROCE) values ('6', '二班', 99);
insert into school (id, CLASS, SROCE) values ('7', '二班', 92);
insert into school (id, CLASS, SROCE) values ('8', '二班', 83);
select *
from (select t.id,
t.class,
t.sroce,
rank() over(partition by t.class order by t.sroce desc) n
from school t)
where n = 1;
简介:
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是对于每个组返回多行,而聚合函数对于每个组只返回一行。
over(partition by class order by sroce) 先按照class分区,再按照sroce排序,order by是个默认的开窗函数。
row_number() over(partition by ... order by ...):返回分组排序后的顺序
rank() over(partition by ... order by ...):返回分组排序后的排名(并列第一名的情况下返回:第一名,第一名,第三名)
dense_rank() over(partition by ... order by ...):返回分组排序后的排名(并列第一名的情况下返回:第一名,第一名,第二名)
count(A) over(partition by ... order by ...):返回分组排序后的总数。
max(A) over(partition by ... order by ...):返回分组排序后的最大值。
min(A) over(partition by ... order by ...):返回分组排序后的最小值。
avg(A) over(partition by ... order by ...):返回分组排序后的平均值。
sum(A) over(partition by ... order by ...):返回分组排序后的累加求和。
lag(A,1) over(partition by ... order by ...):取出上一列的A的值放到本列中。
lead(A,1) over(partition by ... order by ...):取出下一列的A的值放到本列中。
ratio_to_report(A) over(partition by B) 返回分组后的A在其分区B内的占比,A就是分子,B分的组就是分母
公式:
rank() over(partition by A order by B) --按照A分区,按照B排序
根据小案例中数据,使用rank()函数 按照班级分区,然后取班级中的第一名
select *
from (select t.id 序号,
t.class 班级,
t.sroce 成绩,
rank() over(partition by t.class order by t.sroce desc) n返回值
from school t)
--where n = 1
;
结果:对分区间内的查询的记录排名,如下图,有两个并列第一的情况,则有两个第一名,然后是第三名,所以二班为一个区间 返回1,1,3,4 ;一班为一个区间返回1,1,3,4
公式
row_number() over(partition by A order by B) --按照A分区,按照B排序
根据小案例中数据,使用row_number()函数 按照班级分区,然后取班级中的第一名
select *
from (select t.id 序号,
t.class 班级,
t.sroce 成绩,
row_number() over(partition by t.class order by t.sroce desc) n返回值
from school t)
--where n = 1
;
结果:简单的说row_number()从1开始,为每一条分区中的记录返回一个数字,如下图中二班为一个区间 返回1,2,3,4 ;一班为一个区间返回1,2,3,4
综合上述案例,row_number():适用于将select查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生成绩的排名,一般多用于分页查询,
比如查询前10个 查询10-100个学生。
rank() :可以理解为 排名函数,在求第一名成绩的时候,如果同班有两个并列第一,rank()返回两个结果。