目录
3.9 子查询
3.9.1 标量子查询
3.9.2 列级子查询
3.9.3 行级子查询
3.9.4 表级子查询
3.9.5 子查询中特定关键字使用
3.9.6 ‼总结
3.9 子查询
- 在一个select语句中,嵌入了另外一个select语句.那么被嵌入的select语句称之为子查询语句
主查询
- 主要查询的对象第一 条select语句
主查询和子查询的关系
- 子查询是嵌入到主查询中
- 子查询是辅助主查询的,要么充当条件,要么充当数据源
- 子查询是可以独立存在的语句,是一条完整的select语句
子查询分类
子查询返回的数据,多表什么分类
- 标量子查询:子查询返回的结果是一个数据(一行一列)
- 列子查询:返回的结果是一列(一列多行)
- 行子查询:返回的结果是一行(一行多列)
- 表级子查询:返回的结果是多行多列
💦知识点1:
- 标量子查询
- 列子查询
- 行子查询
以上3个子查询,其返回结果都是作为另一个查询的条件来用,都是写在where后面,充当条件辅助主查询
💦知识点2:
充当数据源:数据源select from xx. 这个xx就是数据源,数据源可以是一个表,也可以是查询的结果
3.9.1 标量子查询
查询某个人成绩
🧐例1:查询大于班级学生的平均年龄
-- 步骤一:先计算出班级平均年龄
-- select avg(age) from students
-- -- 21.5714
-- 步骤二:根据步骤一得出的平均年龄得出大于平均年龄的学生
-- 若修改表中的数据,在执行以下的指令就可能会出现错误,因为可能平均年龄变了
select * from students where age > 21.5714
🔶提示:
若修改表中的数据,在执行以上步骤的指令就可能会出现错误,因为可能平均年龄变了
🍎 正确方法:
-- 所有的SQL语句都是从左往右的,先执行select * from students where age> 方向大于后又一个语句,
--就把括号中的语句再次运行,
-- 再把得到结果再给select * from students where age> 使用
select * from students where age > (select avg(age) from students)
🧐例2:查询王昭君的成绩,要求显示成绩
-- 先知道学生的学号,然后再通过学号区查找其的成绩
select * from scores where studentno = (select studentNo from students where nane = '王昭君')
🧐例3:查询王昭君的数据库成绩,要求显示成绩
select score from scores where studentno = (select studentNo from students where nane = '王昭君')
and courseNo = (select courseNo from courses where name = '数据库')
❗ 注意:
因为最终显示的结果从主查询显示,该例的主查询是成绩表,在成绩表中无姓名,无法找到姓名。
该题只要成绩,就可以用子查询,可不用连接查询
🔶做题技巧:
看题要什么,判断用什么查询,从哪个表查。
3.9.2 列级子查询
查询一群人成绩
🧐例1:查询18岁学生成绩,要求显示成绩
-- 步骤一:找出18岁学生
-- select * from students where age = 18
-- 002,003
-- 步骤二:根据找到的学生的学号,查找成绩
--select * from scores where studentNo = '002' or studentNo = '003'
或
select * from scores where studentNo in('002','003')
虽然分步骤得出答案,但存在学生数据表更改的情况,将导致上述方法出错。
🍎正确方法:
select * from scores where studentNo in(select studentNo from students where age = 18)
💦 知识点
列级子查询(3.9.2)与标量子查询(3.9.1)区别:
- 子查询返回结果不同。
- 标量子查询,可以用=、<、>、!=等各种比较符号来做判断
- 列级子查询,无法用比较符号来做,需要用 in 。
3.9.3 行级子查询
🧐例1:查询男生中年龄最大的学生信息
-- 查询男生中年龄最大的学生信息
-- 做的所有查询:
-- 1:先分析问题,根据需要什么信息(学生信息),判断从哪个表查;该例中需要学生信息从学生表查select * from students
-- 2:然后看条件,
-- select * from students
-- where sex = '男' and age =(select max(age) from students where sex = '男')
上述的方法可以总和成以下情况:
-- select *from students where sex = '男' and age = 30
-- select *from students where (sex, age) = ('男', 30)
行级子查询:多个条件都需要有个值,这个值可以在另外一个地方通过一个查询语句将其查询出来;
select *from students
where (sex, age) = (select sex, age from students where sex = '男' order by age desc limit 1)
-- select sex, age from students where sex = '男' order by age desc limit 1
💦知识点:
行级子查询判断条件为不同字段。
在查询时有多个条件,多个条件都需要有个值,这个值可以在另外一个地方通过一个查询语句将其查询出来;
行级子查询 :子查询返回数据是一行多列的。必须一行
3.9.4 表级子查询
表级子查询:指查询出来的结果,在这个结果再继续查询当成表来用。
🧐例1:查询数据库和系统测试的课程成绩
-- 连接查询
-- 先连接在过滤
-- 方式一:
-- select * from scores
-- inner join courses on scores.courseNo = courses.courseNo
-- where courses.name in ('数据库','系统测试')
-- 方式二:也存在临时表在进行过滤,也会影响性能
-- select * from scores, courses
-- where scores.courseNo = courses.courseNo
-- and courses.name in ('数据库','系统测试')
-- 先过滤在连接,
-- 表级子查询:
-- 过滤:select * from courses where courses.name in ('数据库','系统测试')
-- 拿过滤结果,把过滤结果当作一个表(数据源)与成绩表连接.
select * from scores
inner join
(select * from courses where courses.name in ('数据库','系统测试')) as c
on scores.courseNo = c.courseNo
3.9.5 子查询中特定关键字使用
- in范围
格式:主查询where条件in (例子查询)
- any|some任意- -个
格式:主查询 where 列 = any 例子查询
在条件查询的结果中匹配任意一个即可,等价于in
- all
格式:主查询 where 列 = all(列子查询):等于里面所有
格式:主查询 where 列 <> all(列子查询):不等—其中所有
-- select * from students where age in (18, 19, 20)
-- select * from students where age = any(select age from students where age between 18 and 20)
-- select * from students where age = some(select age from students where age between 18 and 20)
-- 大于18,19,20里面任何一个
-- select * from students where age >any(select age from students where age between 18 and 20)
-- 小于18,19,20里面任何一个
-- select * from students where age <any(select age from students where age between 18 and 20)
-- 不等于18,19,20里面任何一个
-- select * from students where age !=any(select age from students where age between 18 and 20)
-- 大于18,19,20里面所有结果
-- select * from students where age >all(select age from students where age between 18 and 20)
-- 不等于18,19,20里面所有结果
select * from students where age !=all(select age from students where age between 18 and 20)
3.9.6 ‼总结
- 无论是表还是查询结果都能当作一个数据源来用,
- 表级子查询,返回结果不是当作条件用,而是当作表来用;写在from 或 join后面
- 前三个子查询返回结果当作条件使用,where后面。
- 标量子查询,可以用=、<、>、!=等各种比较符号来做判断
- 列级子查询,需要用 in 。