获取平均成绩最高的两条记录对

Get pairs of two records with highest average grade

我想计算每条记录的平均成绩,然后得到每个类别平均成绩最高的两条记录。

我的 grade table 看起来像这样:

userid | recordid | grade
123    | 1        | 8
123    | 2        | 1
123    | 3        | 3
123    | 4        | 6
121    | 1        | 3
121    | 2        | 7
121    | 3        | 1
121    | 4        | 8
124    | 1        | 6
124    | 2        | 8
124    | 3        | 9
124    | 4        | 5

record table 是这样的:

id | userid | name | category | year
1  | 101    | Foo  | FooCat   | 2021
2  | 102    | Bar  | FooCat   | 2021
3  | 103    | Foos | BarCat   | 2021
4  | 104    | Bars | BarCat   | 2021

结果将如下所示:

id | name | category | grade_avg
4  | Bars | BarCat   | 6.3
1  | Foo  | FooCat   | 5.7
2  | Bar  | FooCat   | 5.3
3  | Foos | BarCat   | 4.3

我目前正在使用这个 SQL 查询:

SELECT S.id
     , S.name
     , S.category
     , AVG(IB.grade) AS grade_avg
  FROM 
     (SELECT id
           , name
           , category
           , year
           , row_number() over (partition by category) as r 
        FROM records) S
    JOIN grades IB 
        ON IB.recordid = S.id
 WHERE S.r < 3 
   AND S.year=2021
 GROUP 
    BY IB.recordid
 ORDER 
    BY grade_avg DESC

分组效果很好,但分区时的成绩没有按平均成绩排序,因此您只能获得每个类别的前 2 条记录。

获得我想要的结果的最佳查询是什么?这是一个例子,我会把它翻译成我自己使用的,这样我就可以更好地学习使用给定的SQL例子。

如果我没理解错的话,你可以用row_number()枚举行,得到等级最高的两行,然后合计:

select name, category, avg(grade)
from (select g.*, r.name, r.category,
             row_number() over (partition by g.recordid order by g.grade desc) as seqnum
      from grades g join
           records r
           on g.recordid = r.id
      where r.year = 2021
     ) g
where seqnum <= 2
group by name, category;

Here 是一个 db<>fiddle.

编辑:

根据您的结果,您只需要总体平均值,而不是前两行的平均值。这个就简单多了:

select r.name, r.category, avg(grade)
from grades g join
     records r
     on g.recordid = r.id
where r.year = 2021
group by r.name, r.category

我以为基础解决了这个问题,并改变了其中的一些东西。

这对我有用:

SELECT name, category, avg(grade) AS grade_avg
FROM (SELECT name, category, avg(grade) AS grade_avg,
         row_number() over (partition by category ORDER BY grade_avg DESC) as r 
      FROM grades IB JOIN
            records I 
            ON IB.recordid = I.id 
      WHERE year = 2021
      GROUP BY id
   ) S 
WHERE S.r < 3 
ORDER BY grade_avg DESC

所以我按类别划分(按平均成绩排序),按 ID 分组,然后按平均成绩排序。