获得低于科目平均分的平均分

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 [你以前的学生平均成绩] WHERE studentscore your average column name) 【参考方案1】:

由于分数之间存在联系,因此获得第二高分的一种方法是使用此查询:

select max(score)
from scores
where score < (select max(score) from scores)

现在加入subjectsscores(不需要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”

以上是关于获得低于科目平均分的平均分的主要内容,如果未能解决你的问题,请参考以下文章

Pandas DataFrame:如何获取列平均值但仅考虑索引低于我想要获取平均值的行

C语言编程打印出所有低于平均分的分数

mysql 获取单个科目的平均分

在球员计分计划中显示低于平均分

1148: 零起点学算法55——打印所有低于平均分的分数

MR案例 - 分科汇总求月考平均分