目录

 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)

 

MySQL大于平均工资 mysql查询大于平均年龄的人_子查询

 

MySQL大于平均工资 mysql查询大于平均年龄的人_navicat_02

  🧐例2:查询王昭君的成绩,要求显示成绩

-- 先知道学生的学号,然后再通过学号区查找其的成绩

 select * from scores where studentno = (select studentNo from students where nane = '王昭君')

MySQL大于平均工资 mysql查询大于平均年龄的人_数据库_03

  🧐例3:查询王昭君的数据库成绩,要求显示成绩 

select score from scores where studentno = (select studentNo from students where nane = '王昭君')
 and courseNo = (select courseNo from courses where name = '数据库')

 

MySQL大于平均工资 mysql查询大于平均年龄的人_子查询_04

❗ 注意:

因为最终显示的结果从主查询显示,该例的主查询是成绩表,在成绩表中无姓名,无法找到姓名。

        该题只要成绩,就可以用子查询,可不用连接查询

🔶做题技巧:       

        看题要什么,判断用什么查询,从哪个表查。

 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)

 

MySQL大于平均工资 mysql查询大于平均年龄的人_navicat_05

💦 知识点

列级子查询(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

MySQL大于平均工资 mysql查询大于平均年龄的人_MySQL大于平均工资_06

💦知识点:

行级子查询判断条件为不同字段。 

        在查询时有多个条件,多个条件都需要有个值,这个值可以在另外一个地方通过一个查询语句将其查询出来;

行级子查询 :子查询返回数据是一行多列的。必须一行

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

MySQL大于平均工资 mysql查询大于平均年龄的人_navicat_07

 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