我一直试图用一种“不存在”的方法来隔离问题的答案,但我觉得我做得有点太深入了。在我的数据库入门类中,我基本上只能使用一些非常基本的东西。所以,基本上只有INNER、UNION和CASE,也许还有一些其他的东西,但最好假设是最基本的东西。我们还不允许使用coalesce。
发布于 2018-10-30 05:15:27
不确定是否可以仅使用INNER JOIN、UNION和CASE ->,但我找到了一个使用outer join的解决方案(仍然非常简单)。
让我们试着分两步来解决这个问题。
1)让我们看看哪些学生没有完成所有的课程
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)我们得到这个查询没有返回的所有学生(意味着他们已经完成了所有必修课)
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
)
发布于 2018-10-30 06:21:34
我喜欢使用聚合来处理这些事情。
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
和学生。毕竟,学生可以双倍主修。
发布于 2018-10-30 16:38:06
与Preli的答案类似,我会使用左连接来突出显示尚未参加的考试:
SELECT s.code, s.name, p.course
FROM
students s
INNER JOIN
programs p
ON (p.degree = s.degree)
这实际上是学生在课程中必须参加的考试清单。
现在添加他们已经参加的考试,并为他们没有参加的考试保留空值:
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
结果将如下所示:
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(*)):
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,所以他是隐藏的
https://stackoverflow.com/questions/53053400
复制相似问题