获取平均成绩最高的两条记录对
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 分组,然后按平均成绩排序。
我想计算每条记录的平均成绩,然后得到每个类别平均成绩最高的两条记录。
我的 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 分组,然后按平均成绩排序。