【一句话概括本文】
本文旨在通过mysql实验的方式完成10道嵌套查询语言题。
【上题目】
嵌套查询
- 检索选修‘c01’课程的女学生的姓名
- 检索学号比王丽同学小,而年龄比她大的学生姓名
- 检索20210002同学不学的课程的课程号。
- 检索王丽同学不学的课程的课程号。(in和exists两种方法)
- 检索至少选修计算机系所开课程2门以上的女学生姓名
- 查询没有同时选修c02,c03,c04的同学的学号。
- 查询既选修了‘数据库原理’又选修了‘操作系统’的学生的姓名及学号。
- 查询既没有选修‘数据库原理’又没有选修‘操作系统’的学生的姓名及学号。(使用子查询和集合运算两种方法实现)
- 检索选修了全部课程的学生的学号与姓名。
- 检索选修计算机系所开全部课程的学生的学号与姓名。
【上解析】
1.检索选修‘c01’课程的女学生的姓名
方法一:多表查询
SELECT s.Sno, s.Sname, c.Cno, c.Cname
FROM sc,student AS s,department AS d, course AS c
WHERE s.sno=sc.sno AND s.deptNo=d.deptno AND sc.cno=c.cno
AND c.cno='c01' AND s.ssex='女'
运行结果:
方法二:嵌套查询
SELECT sname FROM student
WHERE ssex='女' and sno IN(
SELECT sno
FROM sc
WHERE cno ='c01'
)
运行结果:
2.检索学号比王丽同学小,而年龄比她大的学生姓名
SELECT sname FROM student
WHERE
sno <(
SELECT sno
FROM student
WHERE sname='王丽'
)
AND
sage>(
SELECT sage
FROM student
WHERE sname='王丽'
);
SELECT*FROM student;
运行结果:
3.检索20210002同学不学的课程的课程号。
SELECT cno FROM course
WHERE cno NOT IN (
SELECT cno FROM sc
WHERE sno='20210002'
)
运行结果:
4.检索王丽同学不学的课程的课程号。(in和exists两种方法)
方法一:in方法
SELECT cno FROM course
WHERE cno NOT IN (
SELECT cno FROM sc
WHERE sno IN(
SELECT sno FROM student
WHERE sname='王丽'
)
)
运行结果:
方法二:exists方法
#下面这个不正确。错因:cno=sc.cno处错误
#因为cno会认为是内部变量,也就是sc的cno,那么就没有起到效果
SELECT cno FROM course
WHERE NOT EXISTS(
#王丽同学要学的
SELECT * FROM sc
WHERE sno IN(
SELECT sno FROM student
WHERE sname='王丽'
)
AND cno=sc.cno
)
#下面这个正确
SELECT cno FROM course
WHERE NOT EXISTS(
#王丽同学要学的
SELECT * FROM sc
WHERE sno IN(
SELECT sno FROM student
WHERE sname='王丽'
)
AND course.cno=sc.cno
)
运行结果:
5.检索至少选修计算机系所开课程2门以上的女学生姓名
#首先插入数据
#现在计算机系所开课程只有2门,无论怎样查询结果都为空集。所以增加2门课程
#建议是数据库和操作系统,因为后面的题目可以用
INSERT INTO sc (Sno, Cno, Grade) VALUES ('20210001', 'C06', 98);
INSERT INTO sc (Sno, Cno, Grade) VALUES ('20210002', 'C06', 67);
INSERT INTO sc (Sno, Cno, Grade) VALUES ('20210003', 'C06', 82);
INSERT INTO sc (Sno, Cno, Grade) VALUES ('20210004', 'C06', 49);
INSERT INTO course (Cno, Cname, Pno, Credit, Deptno) VALUES ('C06', '离散数学', NULL, 3, 1);
运行结果:
#错误的写法。group by位置错误
SELECT * FROM student s
WHERE ssex='女'
AND sno IN(
SELECT sno FROM sc
WHERE cno IN(
SELECT cno FROM course
WHERE deptno IN(
SELECT deptno from department
WHERE deptname='计算机系'
)
)
)
GROUP BY sno
HAVING COUNT(*)>2
#正确的写法
SELECT sname FROM student s
WHERE ssex='女'
AND sno IN(
SELECT sno FROM sc
WHERE cno IN(
SELECT cno FROM course
WHERE deptno IN(
SELECT deptno from department
WHERE deptname='计算机系'
)
)
GROUP BY sno
HAVING COUNT(*)>2
)
6.查询没有同时选修c02,c03,c04的同学的学号。
方法一:嵌套查询
SELECT student.sno,student.sname
FROM student
WHERE student.sno NOT IN (
SELECT sc.sno
FROM sc
WHERE sc.cno = 'c02'
AND sc.sno IN (
SELECT sc.sno
FROM sc
WHERE sc.cno = 'c03'
)
AND sc.sno IN (
SELECT sc.sno
FROM sc
WHERE sc.cno = 'c04'
)
)
方法二:集合查询
#里面的select进行的集合合并与subquery很重要
SELECT sno
FROM student
WHERE sno NOT IN (
SELECT sno
FROM (
SELECT sno
FROM sc
WHERE cno = 'c02'
INTERSECT
SELECT sno
FROM sc
WHERE cno = 'c03'
INTERSECT
SELECT sno
FROM sc
WHERE cno = 'c04'
) AS subquery
);
7.查询既选修了‘数据库原理’又选修了‘操作系统’的学生的姓名及学号。
SELECT sno,sname
FROM student
WHERE sno IN (
SELECT sno
FROM (
SELECT sno
FROM sc
WHERE cno IN (
SELECT cno
FROM course
WHERE cname='数据库原理'
)
INTERSECT
SELECT sno
FROM sc
WHERE cno IN (
SELECT cno
FROM course
WHERE cname='操作系统'
)
) AS subquery
);
8.查询既没有选修‘数据库原理’又没有选修‘操作系统’的学生的姓名及学号。(使用子查询和集合运算两种方法实现)
6、7、8是同类型题目。作者建议读者不要光看不练,自己动手做一个,把结果发在评论区吧!
一起进步!
9.检索选修了全部课程的学生的学号与姓名。
#ai逻辑1 not esists
SELECT s.Sname, s.Sno
FROM student s
WHERE NOT EXISTS (
SELECT *
FROM course c
WHERE NOT EXISTS (
SELECT *
FROM sc
WHERE sc.Sno = s.Sno AND sc.Cno = c.Cno
)
);
#ai 逻辑2 group by+having
SELECT s.Sname, s.Sno
FROM student s
JOIN sc ON s.Sno = sc.Sno
GROUP BY s.Sno, s.Sname
HAVING COUNT(DISTINCT sc.Cno) = (SELECT COUNT(DISTINCT Cno) FROM course);
#ai 逻辑3 不使用exists,试着使用all。但是还是需要group by和having
SELECT s.Sname, s.Sno
FROM student s
WHERE s.Sno = ALL (
SELECT sc.Sno
FROM sc
GROUP BY sc.Sno
HAVING COUNT(DISTINCT sc.Cno) = (SELECT COUNT(*) FROM course)
);
运行结果:
10.检索选修计算机系所开全部课程的学生的学号与姓名。
SELECT s.Sname, s.Sno
FROM student s
JOIN department d ON s.deptNo = d.deptNo
WHERE d.deptName = '计算机系' AND NOT EXISTS (
SELECT *
FROM course c
WHERE c.Deptno = d.deptNo AND NOT EXISTS (
SELECT *
FROM sc
WHERE sc.Sno = s.Sno AND sc.Cno = c.Cno
)
);
运行结果:
恭喜您又进步了,本文约3600字!学完本文,您掌握了6个以上嵌套查询语句,特别是in()和集合运算intersect的使用。
非常非常非常非常非常感谢您的观看!如您发现任何错误,欢迎在评论区批评指教!
致谢:
本文特别感谢
@春天的小帆船
@Joker_XWX
提供的参考资料。
没有这些帮助,这篇作品也很难诞生了