首页 / 数据库原理与应用 / SQL数据查询语言DQL(嵌套查询/子查询)

第6章 SQL数据查询语言DQL(嵌套查询/子查询)

6.1 子查询概念

在一个SELECT语句中嵌套另一个SELECT语句,内层查询的结果作为外层查询的条件。子查询可以出现在WHERE、HAVING、FROM等子句中。

6.2 单行子查询

子查询返回单行单列结果,可用=、>、<等比较运算符。

-- 查询与"张三"同系的学生 SELECT * FROM student WHERE sdept = (SELECT sdept FROM student WHERE sname='张三');

6.3 多行子查询

子查询返回多行结果,需用IN、ANY、ALL运算符。

-- 查询选修了"数据库"课程的学生 SELECT sname FROM student WHERE sno IN (SELECT sno FROM sc WHERE cno IN (SELECT cno FROM course WHERE cname='数据库'));

IN:等于子查询结果中的任意一个值

ANY:满足子查询结果中的任意一个条件

ALL:满足子查询结果中的所有条件

6.4 EXISTS

EXISTS判断子查询是否返回记录,返回布尔值(true/false)。

-- 查询有选课记录的学生 SELECT sname FROM student s WHERE EXISTS (SELECT 1 FROM sc WHERE sc.sno = s.sno); -- 查询没有选课记录的学生 SELECT sname FROM student s WHERE NOT EXISTS (SELECT 1 FROM sc WHERE sc.sno = s.sno);

6.5 子查询 vs 连接

很多子查询可以改写成连接,各有优劣:

  • 连接查询:通常效率更高,适合简单关联
  • 子查询:逻辑更清晰,适合复杂条件判断
-- 子查询写法 SELECT * FROM student WHERE sage > (SELECT AVG(sage) FROM student); -- 等价的连接写法 SELECT s.* FROM student s JOIN (SELECT AVG(sage) AS avg_age FROM student) t ON s.sage > t.avg_age;

自学自检小问题

  1. IN和EXISTS有什么区别?什么情况下用EXISTS更好?
  2. 子查询可以嵌套几层?嵌套过多会有什么问题?
  3. 将下面的子查询改写为连接查询:SELECT * FROM A WHERE id IN (SELECT aid FROM B WHERE bid=1);

拓展学习资源

第6章 基础巩固练习
0/5
第1题 选择题
子查询返回多行结果时,外层查询应使用( )
=
>
IN
以上都可以
答案解析
正确答案:C(IN)。多行子查询需要使用IN、ANY或ALL运算符,不能用=直接比较。
第2题 选择题
EXISTS的作用是( )
判断子查询结果是否为空
返回子查询的所有行
删除子查询结果
创建临时表
答案解析
正确答案:A。EXISTS判断子查询是否返回记录,返回布尔值。
第3题 选择题
以下关于子查询和连接的说法,正确的是( )
子查询效率一定比连接高
['连接通常效率更高']
两者完全等价
子查询不能改写为连接
答案解析
正确答案:B。通常连接查询效率更高,但子查询逻辑更清晰。
第4题 选择题
查询比平均年龄大的学生,WHERE子句应为( )
WHERE sage > AVG(sage)
['WHERE sage > (SELECT AVG(sage) FROM student)']
WHERE sage > AVG FROM student
WHERE sage > AVG
答案解析
正确答案:B。聚合函数不能直接用在WHERE中,需要通过子查询获取。
第5题 选择题
NOT EXISTS的作用是( )
子查询返回记录时条件为真
['子查询不返回记录时条件为真']
删除子查询结果
创建索引
答案解析
正确答案:B。NOT EXISTS在子查询没有返回任何记录时为真。
0/0