前言
今天上午起来复习了老师上课讲的选课问题。我总结了三个解法以及一点注意事项。
选课问题介绍
简单来说就是查询某某同学没有选或者选了什么课。然后查询出该同学的姓名,学号,课程号,课程名之类的。
sql文件我上传了。大家可以尝试练一练。
解题代码如下(含思路)
以"查询19105号学生漏选了哪些课程"为例子.
-- 数据库查询的练习
-- 查询19105号学生漏选了哪些课程
-- 法一 使用左外连接+笛卡尔积的方式
-- 1.列出19105号学生应选出的课 笛卡尔积
select Sno,Sname,Cno,Cname from student,course where Sno='19105';
-- 2.进行左外连接 选课的正确逻辑是学号相同且课程号也相同
SELECT * from (select Sno,Sname,Cno,Cname from student,course where Sno='19105') scall left OUTER JOIN
sc ON sc.sno=scall.Sno AND sc.Cno=scall.Cno;
-- 3.筛选出漏选的课,则成绩为null的
-- 错误写法
SELECT * from (select Sno,Sname,Cno,Cname
from student,course where Sno='19105') scall
left OUTER JOIN sc ON sc.sno=scall.Sno AND sc.Cno=scall.Cno AND sc.Grade IS null;
-- 正确写法
SELECT * from (select Sno,Sname,Cno,Cname
from student,course where Sno='19105') scall
left OUTER JOIN sc ON sc.sno=scall.Sno AND sc.Cno=scall.Cno where sc.Grade is NULL;
-- 法二
-- 子查询+IN集合
-- 1.在sc表中找到19105已经选课的课程编号
SELECT Cno FROM sc where sc.Sno='19105';
-- 2.使用not in+子查询方式
SELECT Sno,sname,cno,Cname FROM student,course where Cno not in (SELECT Cno FROM sc where sc.Sno='19105');
-- 3.限定为19105
SELECT Sno,sname,cno,Cname FROM student,course where sno='19105' AND Cno not in (SELECT Cno FROM sc where sc.Sno='19105');
-- 法三
-- 子查询加exists解决
SELECT Sno, sname, Cno, cname
FROM student, course
WHERE student.sno = '19105' -- 明确指定表别名
AND NOT EXISTS (
SELECT 1
FROM sc
WHERE sc.Sno = student.Sno -- 关联当前学生
AND sc.Cno = course.Cno -- 关联当前课程
);
-- 错误写法 注意与正确写法做区分
SELECT Sno, sname, Cno, cname
FROM student, course
WHERE student.sno = '19105' -- 明确指定表别名
AND NOT EXISTS (
SELECT 1
FROM sc,student,course
WHERE sc.Sno = student.Sno -- 关联当前学生
AND sc.Cno = course.2Cno -- 关联当前课程
);
注意事项
结语
byebye~