sql server分组排序取组内第一
场景:查询学校每个班级第一名,或者取每个用户最新的操作记录等类似的场景。
思路:分组排序编号,在取第一条数据
使用函数:row_number() over(partition by 分组字段 order by 排序字段)
rank() over(partition by 分组字段 order by 排序字段)
原始数据:
学号 | 姓名 | 班级 |
1001 | 张三 | 01 |
1002 | 李四 | 01 |
1003 | 王丽 | 02 |
1004 | 李思思 | 02 |
学号 | 课程 | 成绩 |
1001 | 语文 | 88 |
1001 | 数学 | 95 |
1002 | 语文 | 90 |
1002 | 数学 | 93 |
1003 | 语文 | 89 |
1003 | 数学 | 89 |
1004 | 语文 | 90 |
1004 | 数学 | 92 |
结果:
班级 | 学号 | 姓名 | 总分 |
01 | 1001 | 张三 | 183 |
02 | 1004 | 李思思 | 182 |
测试数据准备:
create table tb_student
(sno char(8) not null,
sname varchar(10),
class char(2))
insert into tb_student values('1001','张三','01')
insert into tb_student values('1002','李四','01')
insert into tb_student values('1003','王丽','02')
insert into tb_student values('1004','李思思','02')
create table tb_score
(sno char(4) ,
course varchar(10),
score decimal(3,1))
insert into tb_test values('1001','语文',88)
insert into tb_test values('1001','数学',95)
insert into tb_test values('1002','语文',90)
insert into tb_test values('1002','数学',93)
insert into tb_test values('1003','语文',89)
insert into tb_test values('1003','数学',89)
insert into tb_test values('1004','语文',90)
insert into tb_test values('1004','数学',92)
1、row_number() over(partition by 分组字段 order by 排序字段) 结果
先按班级分组,总分降序得出名次
select *,ROW_NUMBER() over(partition by class order by total_score desc) as rank_no
from(
select class,a.sno,sname,sum(score) total_score
from tb_student a ,tb_score b
where a.sno=b.sno
group by class,a.sno,sname) t

再从结果中取出rank_no为1的行即可

2、rank() over(partition by 分组字段 order by 排序字段) 结果
跟上面一个道理,只是换下函数

从结果上看,两个结果有点差异,主要是存在并列第一的情况,row_number()不考虑并列,按顺序编号,而rank()考虑并列,当值一样时,排名一致,如不存在并列情况,则效果都一样,自己按实际情况选择即可。
测试sql脚本下载:
链接: https://pan.baidu.com/s/1ghKbWvG6nbPnyvdTg4lbng 提取码: rjih
DkME
按照操作说明,程序可以运行,
非常不错,真的是帮大忙了呀,哈哈~~