我一直在尝试采用一种“不存在”的方法来隔离答案,但是我认为我做的太深了。实际上,我仅限于使用真正基础的东西作为数据库类的介绍。因此,基本上只有INNER JOIN,UNION和CASE以及其他一些东西,但可能最好像裸骨头一样假设。我们还不允许使用合并。
答案 0 :(得分:0)
不确定仅使用INNER JOIN,UNION和CASE是否可以实现->但我找到了使用外部联接的解决方案(仍然非常简单)。
让我们尝试通过两个步骤来解决这个问题。
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
)
答案 1 :(得分:0)
我喜欢对这些东西使用聚合。
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
以及学生。毕竟,学生可以双修专业。
答案 2 :(得分:0)
与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>
现在将其简化为仅参加每门课程考试的学生的列表。我们可以通过检查COUNT(e.course)是否与COUNT(p.course)相同来完成此操作,因为COUNT()不计算NULL,因此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,因此他显示(仅一次,因为他被分组了。Doe的COUNT(p.course)为2,但COUNT(e。当然)是0,因为所有值均为空,并且2!= 0,所以他是隐藏的