获得低于科目平均分的平均分
Posted
技术标签:
【中文标题】获得低于科目平均分的平均分【英文标题】:Getting average score lower than the subject’s average score 【发布时间】:2020-06-27 05:03:24 【问题描述】:我有这样的数据:
table students
studentid studentname
1 ani
2 budi
3 caca
4 dedi
.... ...
table subjects
subjectid subjectname
1 MATH
2 ENG
3 SCIENCE
4 ART
.... ...
table scores
studentid subjectname score
1 1 90
2 2 80
3 3 77
4 4 80
.... ... ...
我想得到:
-
哪个科目在所有测试结果中得分第二高。显示主题名称和分数。
预期结果:
subjectname score
ENG 80
ART 80
我试过这个查询:
SELECT st.studentname, su.subjectname, MAX(sc.score)
FROM scores sc
left join subjects su on su.subjectid = sc.subjectid
left join students st on st.studentid = sc.studentid
WHERE score<>(
SELECT MAX(score)
FROM scores);
但是输出:
subjectname score
ENG 80
我该如何处理?
-
打印得分低于该科目每个学生平均分的每个学生。
我的查询是:
SELECT st.studentname, su.subjectname, avg(score), sc.score
FROM scores sc
left join subjects su on su.subjectid = sc.subjectid
left join students st on st.studentid = sc.studentid
WHERE score <
(SELECT AVG(score)
FROM scores );
但结果错误,平均值显示的是所有科目的平均值,而不是每个科目的平均值。
你怎么处理?
【问题讨论】:
你忘记 groupby 了吗? niceee,它的工作,谢谢你,第二个问题怎么样? @lone_coder ? 您在设计数据库时遇到问题。它应该只是调用“subjectid”而不是subjectname吗? (在表分数上) 如果您不打算使用它来引用另一个表,那么创建“subjectid”有什么意义? 关于你的第二个问题。您可以在 groupby 表结果上使用 WHERE 语句。 (例如 SELECT * FROM [你以前的学生平均成绩] WHEREstudentscore
your average column name)
【参考方案1】:
由于分数之间存在联系,因此获得第二高分的一种方法是使用此查询:
select max(score)
from scores
where score < (select max(score) from scores)
现在加入subjects
和scores
(不需要students
)并在WHERE
子句中使用上述查询来获取具有该分数的主题:
select sb.subjectname, sc.score
from subjects sb inner join scores sc
on sc.subjectid = sb.subjectid
where sc.score = (
select max(score)
from scores
where score < (select max(score) from scores)
)
请参阅demo。 结果:
> subjectname | score
> :---------- | ----:
> ENG | 80
> ART | 80
对于第二个问题,这个查询:
select subjectid, avg(score) avg_score
from scores
group by subjectid
返回所有科目的平均分,您可以将它加入到 3 个表中:
select st.studentname, sb.subjectname, t.avg_score
from students st
inner join scores sc on sc.studentid = st.studentid
inner join subjects sb on sb.subjectid = sc.subjectid
inner join (
select subjectid, avg(score) avg_score
from scores
group by subjectid
) t on t.subjectid = sb.subjectid and t.avg_score > sc.score
【讨论】:
【参考方案2】:使用窗口函数:
SELECT subjectname, avg_score
FROM (SELECT su.subjectname, AVG(sc.score) as avg_score,
DENSE_RANK() OVER (ORDER BY AVG(sc.score) DESC) as ranking
FROM scores sc JOIN
subjects su
ON su.subjectid = sc.subjectid
GROUP BY su.subjectname
) s
WHERE ranking = 2;
【讨论】:
谢谢你,但我有一个类似Column 'subjects.subjectname' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
的错误
我从你的答案中得到了输出,但你只显示了所有的平均分数,我想打印每一个分数低于该科目每个学生平均分数的学生。这意味着,您应该打印 student、subject、avg_subject 和 score【参考方案3】:
选择 st.studentname、su.subjectname、sc.score
来自分数sc
在 su.subjectid = sc.subjectid 上左连接主题 su
在 st.studentid = sc.studentid 上左加入学生 st
WHERE sc.score
按 st.studentname,su.subjectname 分组
【讨论】:
它对我不起作用,错误是“有子句”中的“未知列 'sc.score”以上是关于获得低于科目平均分的平均分的主要内容,如果未能解决你的问题,请参考以下文章