mysql使用嵌套查询查询同时选修了某两门课程的学生

本文介绍了如何使用SQL嵌套查询来找出同时选修特定两门课程,如database和java,的学生。通过示例1和示例2详细解释了错误的查询方式以及两种正确的方法,确保查询结果是学生的交集而非并集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了查询已经检修了某两门课程的学生,你可以使用SQL的IN子句来筛选出这些学生。

一、示例1:

假设有一个表student_courses,其中包含学生ID和他们选修的课程ID,

学生ID:sid,学生名字:sname,

选修的课程ID:cid,课程名字:cname,

表如下:

查询示例如下:

SELECT DISTINCT sid
FROM student_courses
WHERE cid IN (cid1, cid2)
GROUP BY sid
HAVING COUNT(DISTINCT cid) = 2;

 这里cid1cid2是你想要查询的两门课程的ID。COUNT(DISTINCT cid)保证了只要学生选了这两门课程,不管他选了多少门课程,只要确实选了这两门,就会被选出来。

结果:

确保你的表名和列名与上述示例相对应。如果你的表名或列名不同,请相应地修改查询。

二、示例2: 

假如有三张表:学生表,选课表,课程表。

学生表:students。

 选课表:choices。

课程表:courses。

 问题:请用嵌套查询找出都选修了database和java课程的学生学号和姓名(交运算)。
错误写法:
select sid,sname 
from students 
where sid in 
    (select sid 
     from choices 
     where cid in 
        (select cid from courses where cname in ('database','java')));
错误结果: 

 学号1215选修了database,但是并没有选修java,却也被查询了出来,和我们想要的结果不太一样。

 这里查出来的是选修了database和选修了java的学生的并集,并不是交集。

正确写法1: 
select sid,sname 
from students natural join choices natural join courses 
where cname='database' 
and sid in 
    (select sid from choices natural join courses where cname = 'java');

 或者

SELECT s.sid, s.sname
FROM student s
JOIN choices t1 ON s.sid = t1.sid AND t1.cid = '10001'
JOIN choices t2 ON s.sid = t2.sid AND t2.cid = '10004'

这个SQL查询语句选取了所有同时选修课程编号为'c002'和'c003'的学生的学生ID和姓名。它通过两次联接takes表,每次联接条件是课程ID分别为'c002'和'c003',并且学生ID需要相同。这样就可以找到同时选修两门课程的学生。 

上面的这两种写法虽然能查询正确的数据,但是如果需要查询的选修课程有很多个,这样写很明显会造成sql语句臃肿。

正确写法2:

只查询学号:

 select distinct ch.sid from choices ch where ch.cid in 
    (select cid from courses where cname in ('database','java')) 
 group by ch.sid 
 having count(distinct ch.cid)=2;

 查询学号和姓名:

select sid,sname 
from students 
where sid in 
    ( select ch.sid 
      from choices ch 
      where ch.cid in 
        (select cid from courses where cname in ('database','java')) 
      group by ch.sid 
      having count(distinct ch.cid)=2);

 结果是:

写后语:

当然除了上述sql写法,用关联查询可能会更简单,这里要求用嵌套查询,所以如上写法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DN金猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值