前段时间做度量系统,遇到一个sql场景,表结构如下
create table STU_EXAM
(
ID NUMBER,
CLASS VARCHAR2(10),
NAME VARCHAR2(200),
SCORE NUMBER
)
/
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (1, 'A', 'Jack', 99);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (2, 'A', 'Monkey', 94);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (3, 'A', 'Sandy', 95);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (4, 'A', 'Tony', 95);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (5, 'B', 'Mark', 90);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (6, 'B', 'Rose', 98);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (7, 'B', 'Apostle', 89);
INSERT INTO STU_EXAM (ID, CLASS, NAME, SCORE) VALUES (8, 'B', 'Anita', 97);
stu_exam表记录的是学生分数,字段有id,班级,名称,分数。
现在要求查询A班中成绩排名前三的学生。
先试一下row_number over 分组函数,按score给学生排个序
select a.*,row_number() over (partition by CLASS order by SCORE desc ) nn
from stu_exam a where class = 'A';
结果发现,Tony和Sandy都是95分 而row_number排序却将其排成2、3名。
再来试试rank函数
select a.*,rank() over (partition by CLASS order by SCORE desc) nn
from stu_exam a where class ='A';
这次雀氏把Tony和Sandy排在一起了,但下面的Monkey却被排成了4,因为要求是排名前三,而不是前三名,是允许并列的,所以仍然不符合预期。
dense_rank函数!!
select a.*,dense_rank() over (partition by CLASS order by SCORE desc) nn
from stu_exam a where class ='A';
bingo! 符合预期。