三、嵌套查询(有些可用连接查询替代,有些不可以)
在写嵌套查询是需要明确条件是父还是子的
这里需要熟练掌握 in与exists
关于in
查询结果返回的是一个集合
关于exists
子查询不返回任何数据,只产生逻辑真和逻辑假
若使用not exists内层查询为空,则外层where子句返回真
--查询订购的产品至少包含了订单102893中所订购产品的订单
SELECT DISTINCT A.order_no AS 订单编号
FROM sale_item A
WHERE a.order_no!='102893'and not EXISTS
(
SELECT *
FROM sale_item B
WHERE B.order_no = '102893' AND not exists (
select *
from sale_item c
where a.order_no=c.order_no and b.book_no=c.book_no))
--查询订购的产品至少包含了订单102893中所订购产品的订单
SELECT DISTINCT A.order_no AS 订单编号
FROM sale_item A
WHERE a.order_no!='102893'and not EXISTS
(
SELECT *
FROM sale_item B
WHERE B.order_no = '102893' AND not exists (
select *
from sale_item c
where a.order_no=c.order_no and b.book_no=c.book_no))
--找出至少选修了“200515004”号同学所选修课程的学生学号(双否)
select sno
from sc a
where sno<>'200515004' and not exists
(select *
from sc c
where sno='200515004' and not exists
(select *
from sc d
where c.cno=d.cno and d.sno=a.sno) )
--找出被所有同学选修了的课程号(双否)
select cno
from course
where not exists
(select *
from student
where not exists
(select *
from sc
where sc.cno=course.cno and sc.sno=student.sno))
--查找各个部门薪资最高的员工信息。提示:排需要用到分组查询,
select a.*
from employee a
where salary=(select max(salary)
from employee b
where a.dept=b.dept)
--4、找出目前业绩未超过300元的员工编号和姓名 (聚合不能在where子句中,故用了group by)
SELECT emp_no 员工编号, emp_name 姓名
FROM employee
WHERE emp_no not IN
(
SELECT sale_id
FROM sales
GROUP BY sale_id
HAVING SUM(total_amt) >= 300
)
--3、找出既选修了“001”又选修了“004”课程的学生姓名
SELECT Sname AS '学生姓名'
FROM Student
WHERE Sno IN
(
SELECT A.Sno
FROM SC A, SC B
WHERE A.Cno = '001' AND B.Cno = '004' AND A.Sno = B.Sno
)
--9、找出“数据库系统概论”这门课成绩最高的学生学号,姓名。
select sno,sname
from student
where sno in
(select sno
from sc
where grade=
(select max(grade)
from sc,course
where sc.cno=course.cno and cname='数据库'))
--10、讲解--找出“沈菁菁”同学所选的课程中,成绩最高的课程信息,包括课程号,课程名。(注意sc和student)
select cno,cname
from course
where cno in
(select cno
from sc
where grade=
(select max(grade)
from student,sc
where sname='沈菁菁'and student.sno=sc.sno))
相关子查询
--查询数据库且数据库成绩大于自己所选课程平均成绩的学生学号、姓名、院系
--父查询要参与子查询,要属于同一个学生
select distinct student.sno,sname,sdept
from student,sc a
where student.sno=a.sno
and cno=(select cno
from course
where cname='数据库'
and grade >
(select avg(grade)
from sc b
where a.sno=b.sno
))
in 是不相关子查询而exists是相关子查询
--not in将不再sale_id里面的也查出来了,结果会多,改成exists就好了
SELECT emp_no 员工编号, emp_name 姓名
FROM employee
WHERE emp_no not IN
(
SELECT sale_id
FROM sales
GROUP BY sale_id
HAVING SUM(total_amt) >= 300
)
--少了结果
SELECT emp_no 员工编号, emp_name 姓名
FROM employee
WHERE emp_no in
(
SELECT sale_id
FROM sales
GROUP BY sale_id
HAVING SUM(total_amt) < 300
)
辨析
1、查询选修了“数据库”且“数据库”成绩大于75分的学生学号、姓名、所在院系。
select student.sno,sname,sdept
from student,sc,course
where student.sno=sc.sno and
sc.cno=course.cno
and cname='数据库' and grade>75;
2、查询选修了“数据库”且“数据库”成绩大于自己选修课程平均分的学生学号、姓名、所在院系。
select student.sno,sname,sdept
from student,sc sc1,course
where student.sno=sc1.sno and sc1.cno=course.cno
and cname='数据库' and grade>(
select avg(grade)
from sc sc2
where sc1.sno=sc2.sno
);
3、查询选修了“数据库”且“数据库”成绩大于75分的学生学号、姓名、所有选修的课程名及成绩。
select student.sno,sname,cname,grade
from student,sc,course
where student.sno=sc.sno and
sc.cno=course.cno and student.sno in(
select sno
from sc,course
where sc.cno=course.cno
and cname='数据库' and grade>75
);