首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >参加了学位中每门课程的考试的学生

参加了学位中每门课程的考试的学生
EN

Stack Overflow用户
提问于 2018-10-30 04:33:55
回答 3查看 224关注 0票数 1

我一直试图用一种“不存在”的方法来隔离问题的答案,但我觉得我做得有点太深入了。在我的数据库入门类中,我基本上只能使用一些非常基本的东西。所以,基本上只有INNER、UNION和CASE,也许还有一些其他的东西,但最好假设是最基本的东西。我们还不允许使用coalesce。

EN

回答 3

Stack Overflow用户

发布于 2018-10-30 05:15:27

不确定是否可以仅使用INNER JOIN、UNION和CASE ->,但我找到了一个使用outer join的解决方案(仍然非常简单)。

让我们试着分两步来解决这个问题。

1)让我们看看哪些学生没有完成所有的课程

代码语言:javascript
复制
select s.code
  from  programs p inner join students s on (p.degree = s.degree)
                   left outer join exams e on (e.course = p.course and e.student = s.code)
  where e.course is null

我们加入学生的程序,然后离开外部加入考试,只过滤那些没有考试行匹配的行(这意味着学生还没有参加考试)。

2)我们得到这个查询没有返回的所有学生(意味着他们已经完成了所有必修课)

代码语言:javascript
复制
select
code, name
from student where code not in (

  select s.code
  from  programs p inner join students s on (p.degree = s.degree)
                   left outer join exams e on (e.course = p.course and e.student = s.code)
  where e.course is null

)
票数 0
EN

Stack Overflow用户

发布于 2018-10-30 06:21:34

我喜欢使用聚合来处理这些事情。

代码语言:javascript
复制
select s.code, s.name, s.degree
from students s join
     programs p
     on p.degree = s.degree join
     exams e
     on e.student = s.code and e.course = p.course
group by s.code, s.name, s.degree
having count(distinct e.course) = (select count(*) from programs p2 where p2.degree = p.degree);

请注意,这包括degree和学生。毕竟,学生可以双倍主修。

票数 0
EN

Stack Overflow用户

发布于 2018-10-30 16:38:06

与Preli的答案类似,我会使用左连接来突出显示尚未参加的考试:

代码语言:javascript
复制
SELECT s.code, s.name, p.course
FROM
  students s
  INNER JOIN
  programs p 
  ON (p.degree = s.degree)

这实际上是学生在课程中必须参加的考试清单。

现在添加他们已经参加的考试,并为他们没有参加的考试保留空值:

代码语言:javascript
复制
SELECT s.code, s.name, p.course, e.course
FROM
  students s
  INNER JOIN
  programs p 
  ON (p.degree = s.degree)

  LEFT OUTER JOIN
  exams e
  ON e.student = s.code AND e.course = p.course

结果将如下所示:

代码语言:javascript
复制
Code   | Name | p.Course | e.Course
stu001 | John | Calc A   | Calc A
stu001 | John | Calc B   | Calc B
stu002 | Doe  | Calc A   | <null>
stu002 | Doe  | Calc B   | <null>

现在,将其缩减为每门课程都参加过考试的学生的列表。我们可以通过检查计数( e.course )与计数( p.course )是否相同来实现这一点,因为NULL不是由COUNT()计数的,因此e.course中出现任何null (无检查)都会减少计数,而不是计算p.course的总出现次数(我也可以使用count(*)):

代码语言:javascript
复制
SELECT s.code, s.name
FROM
  students s
  INNER JOIN
  programs p 
  ON (p.degree = s.degree)

  LEFT OUTER JOIN
  exams e
  ON e.student = s.code AND e.course = p.course

GROUP BY s.code, s.name
HAVING COUNT(p.course) = COUNT(e.course)

John的COUNT(p.Course)将是2,COUNT(e.course)也将是2,因此他显示(只有一次,因为他是分组的。无名氏的计数(p.course)是2,但是计数(e.course)是0,因为所有的值都是空的,2 != 0,所以他是隐藏的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53053400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档