gpt4 book ai didi

sql - 在 SQL 中使用 max()

转载 作者:搜寻专家 更新时间:2023-10-30 22:15:42 24 4
gpt4 key购买 nike

我的家庭作业的一部分是从每个系中找出平均分最高的学生。

查询:

SELECT g.sid as studentID, s.sfirstname, s.dcode, AVG(grade) as average
FROM studentgrades g, student s
WHERE g.sid = s.sid
GROUP BY s.sid

结果:

1   Robert  ger 80.0000
2 Julie sta 77.0000
3 Michael csc 84.0000
4 Julia csc 100.0000
5 Patric csc 86.0000
6 Jill sta 74.5000

为了回答这个问题,我运行了查询

SELECT dcode, averages.sfirstName, MAX(averages.average)
FROM (
SELECT g.sid as studentID, s.sfirstname, s.dcode, AVG(grade) as average
FROM studentgrades g, student s
WHERE g.sid = s.sid
GROUP BY s.sid) averages
GROUP BY dcode

结果:

csc Michael 100.0000
ger Robert 80.0000
sta Julie 77.0000

即使平均值是正确的,但名称却不正确!Julia 是 csc 平均分 100 的人,那么为什么 Michael 会出现?


这是一个例子:

学生参加类(class)并获得这些类(class)的成绩。例如:

student1 from dept1 took course A and got grade 80
student1 from dept1 took course B and got grade 90
student2 from dept1 took course C and got grade 100
student3 from dept2 took course X and got grade 90

运行第一个查询后,我们得到每个学生的平均值

student 1 from dept1 has average 85
student 2 from dept1 has average 100
student 3 from dept2 has average 90

现在我们从每个系中找出平均分最高的学生

dept1, student2, 100
dept2, student3, 90

最佳答案

应该这样做(并且它根据 SQL 标准使用 GROUP BY,而不是 MySQL 实现它的方式)

select s.sid,
s.sfirstname,
s.dcode,
ag.avg_grade
from students s
join (select sid, avg(grade) as avg_grade
from studentgrades
group by sid) ag on ag.sid = s.sid
join (select s.dcode,
max(avg_grade) max_avg_grade
from students s
join (select sid, avg(grade) as avg_grade
from studentgrades
group by sid) ag on ag.sid = s.sid
group by s.dcode) mag on mag.dcode = s.dcode and mag.max_avg_grade = ag.avg_grade
order by mag.avg_grade;

这是如何运作的

这将分几步构建结果。首先它计算每个学生的平均成绩:

select sid, avg(grade) as avg_grade
from studentgrades
group by sid

根据这个语句的结果,我们可以计算出最大值。平均成绩:

select s.dcode,
max(avg_grade) max_avg_grade
from students s
join (select sid, avg(grade) as avg_grade
from studentgrades
group by sid) ag on ag.sid = s.sid
group by s.dcode

现在这两个结果已连接到学生表中。为了便于阅读,假设有一个名为 average_grades(第一个语句)和 max_average_grades(第二个语句)的 View 。

最后的声明基本上是这样做的:

select s.sid,
s.sfirstname,
s.dcode,
ag.avg_grade
from students s
join avg_grades ag on ag.sid = s.sid
join max_avg_grades mag
on mag.dcode = s.dcode
and mag.max_avg_grade = ag.avg_grade;

真正的(我回答中的第一个)只是将名称 avg_gradesmax_avg_grades 替换为我显示的选择。这就是它看起来如此复杂的原因。

可读性更好的标准 SQL 解决方案

在标准 SQL 中,这可以使用公共(public)表表达式来表达,这使得它更具可读性(但本质上是一样的)

with avg_grades (sid, avg_grade) as (
select sid, avg(grade) as avg_grade
from studentgrades
group by sid
),
max_avg_grades (dcode, max_avg_grade) as (
select s.dcode, max(avg_grade) max_avg_grade
from students s
join avg_grades ag on ag.sid = s.sid
group by s.dcode
)
select s.sid,
s.sfirstname,
s.dcode,
ag.avg_grade
from students s
join avg_grades ag on ag.sid = s.sid
join max_avg_grades mag on mag.dcode = s.dcode and mag.max_avg_grade = ag.avg_grade;

但 MySQL 是极少数不支持此功能的 DBMS 之一,因此您需要坚持最初的声明。

需要较少派生表的标准 SQL 解决方案

在标准 SQL 中,使用窗口函数可以将其编写得更短一些以计算部门内的排名(同样这在 MySQL 中不起作用)

with avg_grades (sid, avg_grade) as (
select sid, avg(grade) as avg_grade
from studentgrades
group by sid
)
select sid,
sfirstname,
dcode,
avg_grade
from (
select s.sid,
s.sfirstname,
s.dcode,
ag.avg_grade,
rank() over (partition by s.dcode order by ag.avg_grade desc) as rnk
from students s
join avg_grades ag on ag.sid = s.sid
) t
where rnk = 1;

关于sql - 在 SQL 中使用 max(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13217069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com