多表查询之子查询概念以及典型案例
文章目录
1.子查询的概念以及查询语法
子查询又被称之为嵌套查询,是将查询出来的结果,交给其他的语句来处理。
子查询可以将查询出的结果交给INSERT/UPDATE/DELETE/SELECT中的任意一个来处理,最常用的还是将查询结果交给SELECT语句来使用。
子查询的类型也有很多种,根据查询结果不同,分为:
- 标量子查询:子查询的结果为单个值。
- 列子查询:子查询的结果为某一列的所有值。
- 行子查询:子查询的结果为一行数据。
- 表子查询:子查询的结果为多行多列,相当于一个表数据。
子查询的语法格式:
SELECT*FROM 表1WHERE 字段=(SELECT 字段 FROM 表2)
根据子查询的位置,可以分为WHERE之后、FROM之后、SELECT之后。
例如:
- SELECT (嵌套SQL) FROM 表
- SELECT * FROM (嵌套SQL)
- SELECT * FROM 表 WHERE (嵌套SQL)
以下演示的几种子查询案例,都是由前面创建的人员信息表和部门信息表来演示。
2.标量子查询的应用案例
2.1.标量子查询的概念
标子查询返回的结果通常都是单个值,例如数字、字符串、日期等等,返回单个值都称为标量子查询。
很多应用场景了,通过多表联查等等手段最终计算出一个结果,拿到结果之后还需要在根据结果去查询,基于这些场景都会通过子查询来实现。
2.2.标量子查询案例一
查询出技术运维部的所有员工信息。
思路:首先查询出技术运维部的部门ID,然后根据部门ID去统计人员表的信息。
1)首先查询出技术运维部的部门ID。
select id from bmxxb where bmmc ='技术运维部';
2)根据部门ID去人员信息表查询出具体的人员。
select*from ryxxb where bm_id ='2';
到此为止其实已经查询出我们想要的数据了,但是不太满意这种操作。
3)下面通过子查询的方式来实现,和第二条SQL类似,只不过将值改成了获取这个值的SQL。
select*from ryxxb where bm_id =(select id from bmxxb where bmmc ='技术运维部');
查询结果如下,查询出了运维部的所有人员信息
2.3.标量子查询案例二
查询张子云同事入职之后,新入职的同事。
思路:其实就是查询张子云入职公司以后其他新入职的同事,查询出张子云同事的入职时间,然后只要大于这个入职时间的人员都算是新员工。
1)查询出张子云人员的入职日期。
select rzsj from ryxxb where xm ='张子云';
2)直接使用子查询查询出张子云员工入职之后其他的新入职人员。
select*from ryxxb where rzsj >(select rzsj from ryxxb where xm ='张子云');
3.列子查询的应用案例
3.1.列子查询的概念
子查询返回的结果是一列数据,或者说是由多行的一列数据,这种查询就被称为列子查询。
列子查询返回的结果有多个,通过由特定的操作符来完成数据的查询。
常用的列子查询操作符:IN、NOT IN、ANY、SOME、ALL。
操作符描述IN在指定的集合范围之内,多选一NOT IN在指定的集合范围之内的数据,不选ANY子查询返回的列表中,只要有一个满足即可SOME与ANY等同ALL子查询返回的列表中所有的值都必须满足。
3.2.列子查询案例一
查询出技术运维部、平台开发部所有的员工信息。
思路:和前面标量子查询的案例一类似,只不过这里变成了两个部门,首先分别查询出各个部门的ID,然后根据ID查询出所有的人人员。
1)查询出技术运维部、平台研发部的部门ID。
select id from bmxxb where bmmc in('技术运维部','平台研发部');
2)根据返回的结果通过子查询查询出每个部门的人员信息。
select*from ryxxb where bm_id in(select id from bmxxb where bmmc in('技术运维部','平台研发部'));
查询结果如下,技术运维部和平台开发部的所有人员信息都被查询了出来。
3.3.列子查询案例二
查询比销售部人员薪资都高的人员信息。
思路:首先查询出销售部每个人员的工资列表,然后去查询大于这些工资的人员信息,注意要求的是比销售部每个人的薪资都高的其他人员信息,因此这里就要用到列子查询的ALL操作符了。
1)获取销售部每个人员的工资。
select xz from ryxxb where bm_id in(select id from bmxxb where bmmc ='销售部');
2)根据返回的多列,使用子查询查询出比这些工资都高的人员信息。
select*from ryxxb where xz >all(select xz from ryxxb where bm_id in(select id from bmxxb where bmmc ='销售部'));
查询结果如下,所有比销售部门人员薪资高的其他人员信息都被查询出来了。
3.4.列子查询案例三
查询比技术运维部中任意一人的工资高的人员信息。
思路:首先查询出技术运维部每个人的工资,然后通过列子查询,使用ANY操作符,只要比其中一个人的工资高的人员信息都需要打印出来。
1)查询出技术运维部所有人的工资。
select xz from ryxxb where bm_id in(select id from bmxxb where bmmc ='技术运维部');
2)根据返回的多列,使用子查询查询出比其中一个工资高的人员信息。
select*from ryxxb where xz >any(select xz from ryxxb where bm_id in(select id from bmxxb where bmmc ='技术运维部'));
查询结果如下,技术运维部有个人的薪资是9000,所有比9000高的人员都被查询了出来。
4.行子查询的应用案例
4.1行子查询的概念
子查询返回的结果是一行数据,一行多列的形式,这种子查询就被成为行子查询。
行子查询被INSERT语句嵌套的场景也比较常见。
行子查询的操作符:=、<>、IN 、NOT IN
4.2.行子查询案例一
查询出与张亚男的薪资及直属领导都相同的其他人员信息。
思路:首先要查询出张亚男人员的薪资以及直属领导的ID,然后根据这两个字段的值查询出其他人员的信息。
1)首先获取张亚男的薪资以及直属领导的ID。
select xz,zsld_id from ryxxb where xm ='张亚男';
2)根据查询到的两个值,查询出具有相同值的其他人员信息。
select*from ryxxb where xz ='11000'and zsld_id ='2';
数据虽然是被查询出来了,但是这种方式是我们按照一个一个字段去查出来的,显然这条SQL语句不能将获取该值的查询语句嵌套进去,下面还有一种写法可以做到。
格式:
SELECT * FROM 表名 WHERE (字段1,字段2) = ('值1','值2')
select*from ryxxb where(xz,zsld_id)=('11000','2');
3)此时我们就可以将值列表替换成子查询语句了。
select*from ryxxb where(xz,zsld_id)=(select xz,zsld_id from ryxxb where xm ='张亚男');
查询结果如下,通过行子查询,查询出来我们需要的数据。
5.表子查询应用案例
5.1.表子查询的概念
表子查询返回的结果是多行多列,相当于一张表,这种子查询类型称之为表子查询。
表子查询的应用场景:
- 通过各种联合查询,得到了一个新的数据集,可以通过表子查询将数据写入成一张新表。
- 通过各种联合查询,得到了一个新的数据集,然后把这个结果集当成一张表,再与其他表进行联查。
表子查询的常用操作符是IN,因为是多行多列的结果,无法使用等于。
5.2.表子查询案例一
查询与牛泽阳、张亚男两位员工职业相同、薪资相同的其他员工信息。
思路:首先查询出牛泽阳和张亚男俩人的职位名称以及薪资的数据,然后通过表子查询嵌套的方式,查出来相同数据的其他员工。
1)首先查询出牛泽阳和张亚男俩人的职位和薪资数据。
select zw,xz from ryxxb where xm in('牛泽阳','张亚男');
2)根据查询出来的多行,通过表子查询查询出与这两行数据相同的其他数据。
select*from ryxxb where(zw,xz)in(select zw,xz from ryxxb where xm in('牛泽阳','张亚男'));
5.3.表子查询案例二
查询出入职日期是2019-02-05之后的新入职人员信息,以及部门信息。
思路:首先查询出2019-02-05之后入职的人员信息,通过表子查询的方式嵌套这条SQL语句,将查询结果看做是一张新表,然后与部门表进行左外连接查询。
1)首先查询出2019-02-05之后入职的人员信息。
select*from ryxxb where rzsj >'2019-02-5';
此时就可以把结果集当做是一张新表了。
2)将查询的SQL作为嵌套SQL,放在FROM之后,充当表1,然后把部门表充当表2,通过左外连接的方式查询出人员对应的部门名称。
select ry.*,bm.*from(select*from ryxxb where rzsj >'2019-02-5')as ry leftjoin bmxxb as bm on ry.bm_id = bm.id;
查询结果如下,对应的人员信息以及部门信息都显示了出来。
5.4.表子查询案例三
查询出人员信息表的所有数据,然后写入到员工信息表
思路:通过子查询查询出每一条的记录,然后由INSERT写入新表。
insertinto ygxxb (select*from ryxxb);
数据成功写入。
版权归原作者 Jiangxl~ 所有, 如有侵权,请联系我们删除。