Oracle 的開窗函數 rank,dense_rank,row_number
1、開窗函數和分組函數的區別
分組函數是指按照某列或者某些列分組後進行某種計算,比如計數,求和等聚合函數進行計算。
開窗函數是指基於某列或某些列讓數據有序,數據行數和原始數據數相同,依然能曾現個體數據的原貌。
事例數據
create table student_scores(
stu_id varchar2(10),--學號
stu_name varchar2(20),--姓名
course varchar2(5),--課程
score number(5,2),--分數
constraint pk_stuid_course primary key (stu_id,course)
);
insert into student_scores(stu_id,stu_name,course,score) values(‘10001‘,‘周傑倫‘,‘語文‘,‘85‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10001‘,‘周傑倫‘,‘數學‘,‘96‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10001‘,‘周傑倫‘,‘英語‘,‘67‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10002‘,‘謝霆鋒‘,‘語文‘,‘71‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10002‘,‘謝霆鋒‘,‘數學‘,‘97‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10002‘,‘謝霆鋒‘,‘英語‘,‘100‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10003‘,‘蘇有朋‘,‘語文‘,‘79‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10003‘,‘蘇有朋‘,‘數學‘,‘65‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10003‘,‘蘇有朋‘,‘英語‘,‘80‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10004‘,‘劉德華‘,‘語文‘,‘41‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10004‘,‘劉德華‘,‘數學‘,‘61‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10004‘,‘劉德華‘,‘英語‘,‘62‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10005‘,‘小龍女‘,‘語文‘,‘94‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10005‘,‘小龍女‘,‘數學‘,‘95‘);
insert into student_scores(stu_id,stu_name,course,score) values(‘10005‘,‘小龍女‘,‘英語‘,‘96‘);
2、分組函數:group by
按照課程進行分組,可以進行如下計算
select course,count(*) cou,avg(score) avgs,max(score) maxs,min(score) mins
from student_scores
group by course;
| COURSE | COU | AVGS | MAXS | MINS |
1 | 數學 | 5 | 82.8 | 97 | 61 |
2 | 語文 | 5 | 74 | 94 | 41 |
3 | 英語 | 5 | 81 | 100 | 62 |
3、開窗函數:rank() ,dense_rank(),row_number()
每個學科按照分數倒序排名
select stu_id,stu_name,course,score,rank() over(partition by course order by score desc) rankfrom student_scores;
| STU_ID | STU_NAME | COURSE | SCORE | RANK |
1 | 10002 | 謝霆鋒 | 數學 | 97.00 | 1 |
2 | 10001 | 周傑倫 | 數學 | 96.00 | 2 |
3 | 10005 | 小龍女 | 數學 | 95.00 | 3 |
4 | 10003 | 蘇有朋 | 數學 | 65.00 | 4 |
5 | 10004 | 劉德華 | 數學 | 61.00 | 5 |
6 | 10002 | 謝霆鋒 | 英語 | 100.00 | 1 |
7 | 10005 | 小龍女 | 英語 | 96.00 | 2 |
8 | 10003 | 蘇有朋 | 英語 | 80.00 | 3 |
9 | 10001 | 周傑倫 | 英語 | 67.00 | 4 |
10 | 10004 | 劉德華 | 英語 | 62.00 | 5 |
11 | 10005 | 小龍女 | 語文 | 94.00 | 1 |
12 | 10001 | 周傑倫 | 語文 | 85.00 | 2 |
13 | 10003 | 蘇有朋 | 語文 | 79.00 | 3 |
14 | 10002 | 謝霆鋒 | 語文 | 71.00 | 4 |
15 | 10004 | 劉德華 | 語文 | 41.00 | 5 |
註意分組函數和開窗函數針對數據在維度上的變化,分組函數使個體數據小時。開窗函數保留個體。
Oracle 的開窗函數 rank,dense_rank,row_number