子查询,顾名思义就是嵌套的别的查询语句中的查询,因为很多时候查询不是一蹴而就的,往往是需要一个中间结果集作一个过渡的,而我们的子查询就是用于这种中间结果集过渡。
1、出现在选择列表中
这种情况并不多见,但也是一种使用场景,可以应用在 insert,update,delete 和 select 语句中,我们分别来看。
insert:
insert into students values(5,'yang',(select avg(id) from departs),1);
我们向 students 表中插入一条数据,age 字段的值为 departs 表 id 字段的平均值,这个例子本身没多大意义,但是我为你演示的是语法。
update:
update students set age=(select avg(id) from departs) where students.id =1;
记住,子查询一定要使用小括号括起来,强调一种优先级,不然会与外查询产生冲突报错。
delete:
delete from students where id= (select avg(id) from departs)
select 语句的子查询类似,不再赘述了。再次强调下,这种模式下使用子查询并不多见,不要刻意为了装逼写成这样,你会被打的!
2、含有in和exists的子查询
in 这个关键字相信大家也不陌生,我们之前介绍 select 基本查询的时候介绍过,它强调的是一种集合的概念,可以视作一种逻辑运算符。
比如:
select * from students where id in(2,3,4,5,6)
我们换成子查询就变成:
select * from students where id in (select id from departs)
这时的子查询返回的是一个集合,而不再是一个常量。
exists 带来的子查询主要思路:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE 或 FALSE)来决定主查询的数据结果是否得以保留。
只要子查询有返回行,即返回 true,否则返回 false。
基本语法如下:
select [select_list]from [table] where [not] exists [子查询]
看起来挺复杂,我们举个例子你就明白了:
以我们的学生表来说,每个学生都存储了一个学院字段信息,通过这个字段的值可以具体查到学院的名字,那么假如现学生表中有大量陈腐数据,无效或为空的学院 id 对应的数据都是有些有问题的数据,现需要查出这些数据
departs 表如下:
students 表如下:
显然,学生表中的第2-3-7行数据有问题,他们的学院 id 非法,我们需要使用 SQL 找到这两条数据。
select * from students where not exists (select * from departs where students.departId = departs.id)
执行 SQL,看看结果:
首先外查询拿到 students 表的所有数据,where 子句会遍历每一行,执行子查询过滤筛选,如果整个 where 子句返回为 true,代表该行记录有效应该被查询出来,否则将抛弃该行,继续遍历。
关于子查询暂时句介绍到这,基本核心的内容都已经附带例子的介绍了,什么嵌套子查询不过是多套了一层而已,相信你能够理解,这里不再赘述了。