【问题标题】:SQL: return lector, whose ALL students passed with Excellent markSQL:return lector,其所有学生均以优异成绩通过
【发布时间】:2017-11-27 10:55:04
【问题描述】:

下表:学生姓名、学生讲师姓名(一个讲师可以有几个学生)、课后成绩。

Stud    Lector  Mark
-----------------
Joe     Mr.A    5
Steve   Mr.A    4
Bob     Mr.B    5
Jim     Mr.D    5
Kai     Mr.C    4
Mo      Mr.A    3
Hue     Mr.B    3
Mia     Mr.D    5

什么查询将返回讲师,其所有学生都出色地通过了课程(获得 5 分)。在我们的例子中 - Mr.D 应该作为查询结果返回。

【问题讨论】:

  • 提示:NOT EXISTS(...)
  • 一个给定的讲师可以让同一个学生出现多次,例如一次得1分,一次得5分?在这种情况下应该怎么办?
  • 嗨蒂姆。我想,这个学生不再是“优秀”的人了,讲师应该被取消为优秀讲师:)。通常——为什么不呢?学生有时会被提及。我们可以添加诸如“课程”之类的列

标签: mysql sql


【解决方案1】:

我认为最简单的方法是通过 lector 上的聚合:

SELECT Lector
FROM yourTable
GROUP BY Lector
HAVING SUM(CASE WHEN Mark < 5 THEN 1 ELSE 0 END) = 0;

这种方法的好处是它可以根据您要实现的实际逻辑仔细阅读。也就是说,我们只需检查每个讲师的分数,并确保没有出现低于 5 分的分数。

Demo

【讨论】:

  • 我对这个答案的简单性感到谦卑,但它之所以有效,是因为您选择了mark 的最大值。它不适用于一般情况,例如拥有所有4 标记的讲师。也许简单地更改WHEN Mark != 5 THEN 更灵活?然后可以对任何给定的标记使用相同的查询,或者使用WHEN MARK NOT IN (...) 的标记。你知道吗,至高无上的功夫,你可以简单地编码HAVING SUM(mark != 5) = 0,因为在mysql中true是1,false是0!
  • @Bohemian 我已要求 OP 进行澄清。目前尚不清楚在这种情况下我们应该如何进行。无论如何,我的查询很可能只需要对HAVING 子句进行一点改动。
  • 我认为不需要澄清。我的意思是如果问题是“找到所有分数为n的讲师”,其中OP的问题是一个具体案例,答案将根据我之前的评论,但您的查询不会有用,因为它假定除n 之外的所有标记都小于n
  • @Bohemian 一个给定的讲师有一个学生是 4 和 5。你会怎么计算这个?
  • 我不会计算有学生得分为 4 和 5 的讲师,因为存在得分低于 5 的学生。此外,鉴于架构,似乎讲师/学生关系基数是 1。如果学生对给定讲师的得分超过 1,我希望另一列(可能是日期)打破关键关系
【解决方案2】:

您必须将表连接到自身;一次获得优秀的分数,再次获得可能不太优秀的分数。有几种方法可以实现这一点,但最好的恕我直言:

select distinct a.lector
from mytable a
left join mytable b on a.lector = b.lector
    and b.mark != 5
where a.mark = 5
and b.mark is null

这里的诀窍是使用从优秀分数到差分数的外连接,并使用b.mark is null 来确保实际上没有差分数。

【讨论】:

  • 我不同意。我仍然没有看到您所涵盖的边缘情况,并且提供一些突出显示这一点的示例数据将对其他阅读此问题的人有所帮助。
  • @tim 这不是缺少的边缘情况。你的回答是边缘情况。没关系,算了。如果您在阅读了我所有的 cmets 之后现在还没有看到它,那么更多的 cmets 将无济于事。
猜你喜欢
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 2021-01-16
相关资源
最近更新 更多