已经参加过各学位课程考试的学生?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (46)

PostgreSQL 数据:

Exams:  
- Course  (code unique)  
- Student  (unique code)  
- Date   (MM/DD)  

Students:  
- Code (unique)  
- Name (unique)  
- Degree  

Programs:  
- degree (name)   
- Course (course list)  

例:

Exams:  
Course  |  Student | Date   
---------------------------  
Calc A  |  stu001  |  01/01  
Calc B  |  stu001  |  01/02  
Calc C  |  stu002  |  02/02  

Students:
Code  |  Name  |  Degree  
----------------------
stu001  |  John  | Math  
stu002  |  Doe  |  Math

Programs:  
Degree  | Course
-------------------
Math  |  Calc A   
Math  |  Calc B  
Bio  |  Bio 1  

预期产出:

Code  |  Name  
stu001  | John 

因为数学学位只需要Calc A和Calc B,John已经参加了这两门课程的考试。

到目前为止我做了什么:

SELECT students.code, students.name
FROM exams, students
WHERE NOT EXISTS
(
    SELECT *
    FROM exams
    WHERE students.uun NOT IN ( 
                SELECT exams.student
                    FROM exams
                    WHERE students.UUN = EXAMS.STUDENT
                    )
        )

我一直在努力做一个“不存在”的方法来分离答案,但我想我已经走得太深了。对于我的数据库类介绍,我基本上只使用了非常基本的东西。所以,基本上只有INNER JOIN,UNION和CASE以及其他一些东西,但最好的假设就像裸骨头一样。我们还不允许使用合并。

提问于
用户回答回答于

不确定这是否可以只使用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

)
用户回答回答于

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

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学生和学生。毕竟,学生可以加倍专业。

扫码关注云+社区

领取腾讯云代金券