![](/img/trans.png)
[英]How to find all the courses in which the set of enrolled students is a superset of the students who have enrolled in some course C
[英]Find students who have registered all course that a specific student did
我有三个表:学生、课程和注册。 我想使用 select 语句(单个查询)来查找注册了 S_ID:1 学生所做的所有课程的学生的ID(s_id) 。 表格如下:
学生 (s_id, s_name)
1、约翰
2、杰森
3、汤姆
课程 (c_id, c_name)
1、数学
2、科学
3、运动
注册 (s_id, c_id)
1,1
1,2
2,1
2,3
3,1
3,2
3,3
在这个简单的例子中,就是3号学生,因为他也注册了1号和2号课程(2号学生没有注册2号课程)。 请帮我解决这个问题。 非常感谢!
应该是这样的:
Select * from student where id in (select s_id fom Registration where c_id in (select c_id from Registration where s_id = 1))
当(s_id,c_is)唯一时,Caius Jard的查询是正确的,但如果一个学生可以多次注册一门课程,则应更改代码如下:
SELECT s_id
FROM registration
WHERE c_id IN (SELECT c_id FROM registration WHERE s_id = 1) AND s_id <> 1
GROUP BY s_id
HAVING COUNT(*) >= (SELECT COUNT(*) FROM registration WHERE s_id = 1 GROUP BY c_id)
使用基本的sql:
SELECT s_id
FROM registration
WHERE c_id IN (SELECT c_id FROM registration WHERE s_id = 1) AND s_id <> 1
GROUP BY s_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM registration WHERE s_id = 1)
这将获取课程 1 为 (1,2) 注册的列表,然后获取课程为 1 或 2 的所有其他记录的列表。此时学生 2 将被选中,但随后我们对记录进行分组和计数有。 学生 2 只会出现一次,因此他未能通过 HAVING 测试,这实质上要求学生在列表中出现两次。 因为学生3注册了3门课程,包括1和2,在他被分组和计数之前,他会出现两次(一次为1,一次为2)。 计数时,他的计数为 2,这与 HAVING 中的要求计数相匹配
一种方法是为每个学生生成您关心的课程的所有组合。 然后使用left join
将这些与实际存在的课程相匹配,并检查所有课程是否都被考虑在内:
select s.s_id
from student s cross join
(select distinct c_id
from registration r
where r.s_id = 2
) c left join
registration r
on r.c_id = c.c_id and r.s_id = s.s_id
group by s.s_id
having count(*) = count(r.s_id);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.