锋利的SQL:从分组中取前几行数据(二)

2014-11-24 09:58:20 · 作者: · 浏览: 2
的名次RANK( )和DENSE_RANK( )出现了差异,从两人并列第1的角度讲,他们两人之后的名次应当是第2,这是DENSE_RANK( )函数的排名方式,也称为密集排名,因为它的名次之间没有间隔;前面已经有2个人100分了,他们后面的人应当是第3个高分者,从这个角度理解,后面的名次应当是第3,这是RANK( )的排名方式。
例如,下面的语句按班级分组、按成绩降序密集排名,查询结果如表5所示。与上面使用联接获取前2名的方式相比,使用排名函数可以正确处理成绩并列现象。同样是获取成绩前2名,存在成绩并列时,使用排名函数从每个班级中取出的人数有可能超过2个。
www.2cto.com
SELECT ClassID, StuName, Achi,
DENSE_RANK() OVER(PARTITION BY ClassID ORDERBY Achi DESC) AS rank_rn
FROM Students;
表5 排序结果
ClassID
StuName
Achi
rank_rn
1
张山
100
1
1
王磊
95
2
1
李明
90
3
2
孙科
100
1
2
王智
90
2
2
赵强
80
3
3
李海
95
1
从上表可以看出,我们只要取出rank_rn小于或等于2的考生即可。下面是完整的查询语句,在性能方面,该语句要高于联接方式。
www.2cto.com
WITH StuRank(ClassID, StuName, Achi, rank_rn)
AS
(SELECT ClassID, StuName, Achi,
DENSE_RANK() OVER(PARTITION BY ClassID ORDER BY Achi DESC)
FROMStudents
)SELECT * FROMStuRank WHERE rank_rn <= 2;