每个GROUP BY限制SQL查询

时间:2013-05-31 02:16:02

标签: sql sql-server postgresql greatest-n-per-group

我有20个教室,每个教室有50个学生。

是否可以在一个查询语句中找到每个教室中最好的10名学生?

表“klas”:

int id
int cla_id
int stu_id
int final_score

2 个答案:

答案 0 :(得分:6)

在大多数数据库中,您可以这样做:

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等数据库中不起作用,不支持row_number()等ANSI标准窗口函数。

row_number()函数将顺序编号应用于行。由于cla_id子句,在您的情况下,每个partition by的编号重新开始。由于final_score,编号为“1”的行是order by final_score desc最大的行。这也可以应用于min()sum()等聚合函数。在这种情况下,它提供聚合值,但是在原始数据集的每一行上(相当于进行聚合和连接,但通常更有效)。

答案 1 :(得分:2)

如果第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