我有20个教室,每个教室有50名学生。
是否有可能在单个查询语句中找到每个教室中 10 名最好的学生?
表“klas”:
int id
int cla_id
int stu_id
int final_score
我有20个教室,每个教室有50名学生。
是否有可能在单个查询语句中找到每个教室中 10 名最好的学生?
表“klas”:
int id
int cla_id
int stu_id
int final_score
在大多数数据库中,您可以执行以下操作:
select k.*
from (select k.*,
row_number() over (partition by cla_id order by final_score desc) as seqnum
from klas
) k
where seqnum <= 10;
这将检索每个班级的 10 名得分最高的学生。它不适用于 MySQL 和 MS Access 等不支持 ANSI 标准窗口函数(如row_number()
.
该row_number()
函数对行应用顺序编号。在您的情况下,每个编号都会重新开始cla_id
- 因为该partition by
子句。编号为“1”的行是最大的行final_score
- 因为order by final_score desc
. 这也可以应用于聚合函数,如min()
和sum()
。在这种情况下,它提供聚合值,但在原始数据集的每一行上(相当于进行聚合和连接,但通常更有效)。
如果第 10 名最好的学生与第 11 名或第 12 名的分数相同,则您不想只返回数字 10,还希望返回 11 和 12。所以在这种情况下,最好使用 RANK(),如下所示:
;WITH ranking
AS
(
SELECT *
,RANK() OVER (PARTITION BY cla_id
ORDER BY final_score DESC) AS rank
FROM klas
)
SELECT cla_id
,rank
,stu_id
FROM ranking
WHERE rank <= 10
ORDER BY cla_id
,rank