![f877bbe15f14fdffaa6676d4ddda5beb.png](https://i-blog.csdnimg.cn/blog_migrate/38f30ec3676947421247400b9643b871.jpeg)
到现在为止我们处理的查询语句都是单条语句查询,sql允许创建子查询,即嵌套查询,一个查询语句(select-from-where)在另外的查询语句中使用,子查询的select查询总是使用圆括号括起来。子查询可以返回一个值或者一组值,用于前面查询计算或者过滤。
一、where in 子查询
in关键字用于where子句中用来判断查询的表达式是否在多个值的列表中。返回满足in列表中的满足条件的记录。查询所有数据库课程大于80分的学生基本信息;
- 查询数据库课程的ID
- 获取数据库课程ID大于80分的学生ID
- 根据学生ID获取相关信息
SELECT NO,NAME FROM course WHERE NAME='数据库';
返回结果C01;
SELECT sno,grade FROM coursegrade WHERE cno='C01' ANDgrade>80;
返回结果9512101和9512102;
SELECT * FROM student WHERE NO IN(9512101,9512102);
返回所有学生信息;整合所有语句得到结果:
SELECT * FROM student WHERE NO IN(SELECT sno FROMcoursegrade WHERE cno='C01' AND grade>80 );
![ad9a73783fa4b76f8fb8d1bf5b9a96c2.png](https://i-blog.csdnimg.cn/blog_migrate/9012dd02a98bd3769057970acd7ca4a5.jpeg)
二、作为计算字段的子查询
计算所有学生各科成绩
SELECT NAME,department, (SELECT SUM(grade) FROM coursegrade WHERE coursegrade.sno=student.no) AS course Total FROM student;
![75f17c8071b9ceac1e1a2400c581381b.png](https://i-blog.csdnimg.cn/blog_migrate/209766456b58e7ba4e9ff4af7b3ff596.jpeg)
三、whereEXISTS子查询
EXISTS是sql中的逻辑运算符号,如果子查询有结果集返回,那么就为True,EXISTS代表“存在”的意义,它只查找满足条件的那些记录,一旦找到第一个匹配的记录后,就马上停止查找。查询如果存在不及格学生则返回所有学生信息;
SELECT * FROM student WHERE EXISTS (SELECT * FROM coursegrade WHERE grade<60);
![c3343ca83f0ee968a594302ebd8ad0f1.png](https://i-blog.csdnimg.cn/blog_migrate/48a9d275787c6743a7dea5414faa8ac2.jpeg)
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
四、where all any子查询
all是sql中的逻辑运算符好,如果一系列的比较都为true,那么结果才能为true。返回的结果集为多个的子查询,为多行子查询,多行子比较符有 IN(等于列中任意一个)、ANY(和子查询返回的某个值比较),ALL(和子查询返回的所有值比较)。查询其他课程中比数据库课程的所有分数低的学生的学号、姓名、课程名和分数。
获取数据库课程的所有分数:
SELECT grade FROM coursegrade WHERE coursegrade.cno = 'C01';
获取比所有数据库课程分数低的学生的信息:
SELECT NO, NAME, department, coursegrade.grade FROM student, coursegrade WHERE (student.no=coursegrade.sno) AND coursegrade.grade < ALL(SELECT grade FROM coursegrade WHERE coursegrade.cno= 'C01' );
![f93e1a75dc9b620546167a2538b38a69.png](https://i-blog.csdnimg.cn/blog_migrate/fa14b54494c170426fce18cc1394bf5e.jpeg)
五、where 运算符子查询
查询平均成绩比‘吴斌’大的学生id,姓名,平均成绩查询‘吴斌’的平均成绩:
SELECT AVG(grade) FROM student s JOIN coursegrade g ON s.no= g.sno WHERE s.name = '吴斌';
查询平均成绩比‘吴斌’大的学生id,姓名,平均成绩等信息:
SELECT NO, NAME, AVG(grade) FROM student s, coursegrade c WHERE s.no = c.sno GROUP BY NO HAVING AVG(grade) > (SELECT AVG(grade) FROM student s JOIN coursegrade g ON s.no = g.sno WHERE s.name = '吴斌');
![a0f77c8e436d80fd69e5b0d6aa441316.png](https://i-blog.csdnimg.cn/blog_migrate/d0fb4f28a4032a3f2724a7f15f10382d.jpeg)
六、多个子查询联合使用
查询数据库成绩比数学成绩高的学生的信息和相关分数:
- 先找两门课程成绩
- 关联查询,数据库成绩比数学成绩高
- 根据Id获取相关信息和分数
SELECT * FROM Student RIGHT JOIN(SELECTt1.sno,class1,class2
-- 关联查询,数据库成绩比数学成绩高
FROM (SELECT sno,grade AS class1 FROM coursegradeWHERE cno = 'c01') AS t1,
-- 两门课程成绩查询
(SELECT sno,grade AS class2 FROM coursegrade WHERE cno = 'c02') AS t2WHEREt1.sno = t2.sno AND t1.class1 > t2.class2) re ON Student.no =re.sno;
![890068ebb1793da501ee8d5f73349033.png](https://i-blog.csdnimg.cn/blog_migrate/7fe85b1bdfcdab912051dbb4a7d2cd90.jpeg)
使用子查询的好处:具体数据改变不需要改语句,容易维护。坏处效率会低,而且随着语句的增长可读性不强,不建议经常使用。