第27讲:多表查询之子查询概念以及典型案例

多表查询之子查询概念以及典型案例

1.子查询的概念以及查询语法

子查询又被称之为嵌套查询,是将查询出来的结果,交给其他的语句来处理。

子查询可以将查询出的结果交给INSERT/UPDATE/DELETE/SELECT中的任意一个来处理,最常用的还是将查询结果交给SELECT语句来使用。

子查询的类型也有很多种,根据查询结果不同,分为:

  • 标量子查询:子查询的结果为单个值。
  • 列子查询:子查询的结果为某一列的所有值。
  • 行子查询:子查询的结果为一行数据。
  • 表子查询:子查询的结果为多行多列,相当于一个表数据。

子查询的语法格式:

SELECT * FROM1 WHERE 字段=(SELECT 字段 FROM2)

根据子查询的位置,可以分为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 = '技术运维部';

image-20220519223925111

2)根据部门ID去人员信息表查询出具体的人员。

select * from ryxxb where bm_id = '2';

image-20220519224143096

到此为止其实已经查询出我们想要的数据了,但是不太满意这种操作。

3)下面通过子查询的方式来实现,和第二条SQL类似,只不过将值改成了获取这个值的SQL。

select * from ryxxb where bm_id = (select id from bmxxb where bmmc = '技术运维部');

查询结果如下,查询出了运维部的所有人员信息

image-20220519224402795

2.3.标量子查询案例二

查询张子云同事入职之后,新入职的同事。

思路:其实就是查询张子云入职公司以后其他新入职的同事,查询出张子云同事的入职时间,然后只要大于这个入职时间的人员都算是新员工。

1)查询出张子云人员的入职日期。

select rzsj from ryxxb where xm = '张子云';

image-20220519230943587

2)直接使用子查询查询出张子云员工入职之后其他的新入职人员。

select * from ryxxb where rzsj > (select rzsj from ryxxb where xm = '张子云');

image-20220519231054792

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 ('技术运维部','平台研发部');

image-20220519232731445

2)根据返回的结果通过子查询查询出每个部门的人员信息。

select * from ryxxb where bm_id in (select id from bmxxb where bmmc in ('技术运维部','平台研发部'));

查询结果如下,技术运维部和平台开发部的所有人员信息都被查询了出来。

image-20220519232842631

3.3.列子查询案例二

查询比销售部人员薪资都高的人员信息。

思路:首先查询出销售部每个人员的工资列表,然后去查询大于这些工资的人员信息,注意要求的是比销售部每个人的薪资都高的其他人员信息,因此这里就要用到列子查询的ALL操作符了。

1)获取销售部每个人员的工资。

select xz from ryxxb where bm_id in (select id from bmxxb where bmmc = '销售部');

image-20220519233839903

2)根据返回的多列,使用子查询查询出比这些工资都高的人员信息。

select * from ryxxb where xz > all (select xz from ryxxb where bm_id in (select id from bmxxb where bmmc = '销售部'));

查询结果如下,所有比销售部门人员薪资高的其他人员信息都被查询出来了。

image-20220519234103464

3.4.列子查询案例三

查询比技术运维部中任意一人的工资高的人员信息。

思路:首先查询出技术运维部每个人的工资,然后通过列子查询,使用ANY操作符,只要比其中一个人的工资高的人员信息都需要打印出来。

1)查询出技术运维部所有人的工资。

select xz from ryxxb where bm_id in (select id from bmxxb where bmmc = '技术运维部');

image-20220519234522482

2)根据返回的多列,使用子查询查询出比其中一个工资高的人员信息。

select * from ryxxb where xz > any (select xz from ryxxb where bm_id in (select id from bmxxb where bmmc = '技术运维部'));

查询结果如下,技术运维部有个人的薪资是9000,所有比9000高的人员都被查询了出来。

image-20220519234639465

4.行子查询的应用案例

4.1行子查询的概念

子查询返回的结果是一行数据,一行多列的形式,这种子查询就被成为行子查询。

行子查询被INSERT语句嵌套的场景也比较常见。

行子查询的操作符:=、<>、IN 、NOT IN

4.2.行子查询案例一

查询出与张亚男的薪资及直属领导都相同的其他人员信息。

思路:首先要查询出张亚男人员的薪资以及直属领导的ID,然后根据这两个字段的值查询出其他人员的信息。

1)首先获取张亚男的薪资以及直属领导的ID。

select xz,zsld_id from ryxxb where xm = '张亚男';

image-20220520140704476

2)根据查询到的两个值,查询出具有相同值的其他人员信息。

select * from ryxxb where xz = '11000' and zsld_id = '2';

image-20220520140850103

数据虽然是被查询出来了,但是这种方式是我们按照一个一个字段去查出来的,显然这条SQL语句不能将获取该值的查询语句嵌套进去,下面还有一种写法可以做到。

格式:SELECT * FROM 表名 WHERE (字段1,字段2) = ('值1','值2')

select * from ryxxb where (xz,zsld_id) = ('11000','2');

image-20220520140850103

3)此时我们就可以将值列表替换成子查询语句了。

select * from ryxxb where (xz,zsld_id) = (select xz,zsld_id from ryxxb where xm = '张亚男');

查询结果如下,通过行子查询,查询出来我们需要的数据。

image-20220520140850103

5.表子查询应用案例

5.1.表子查询的概念

表子查询返回的结果是多行多列,相当于一张表,这种子查询类型称之为表子查询。

表子查询的应用场景:

  • 通过各种联合查询,得到了一个新的数据集,可以通过表子查询将数据写入成一张新表。
  • 通过各种联合查询,得到了一个新的数据集,然后把这个结果集当成一张表,再与其他表进行联查。

表子查询的常用操作符是IN,因为是多行多列的结果,无法使用等于。

5.2.表子查询案例一

查询与牛泽阳、张亚男两位员工职业相同、薪资相同的其他员工信息。

思路:首先查询出牛泽阳和张亚男俩人的职位名称以及薪资的数据,然后通过表子查询嵌套的方式,查出来相同数据的其他员工。

1)首先查询出牛泽阳和张亚男俩人的职位和薪资数据。

select zw,xz from ryxxb where xm in ('牛泽阳','张亚男');

image-20220520160028394

2)根据查询出来的多行,通过表子查询查询出与这两行数据相同的其他数据。

select * from ryxxb where (zw,xz) in (select zw,xz from ryxxb where xm in ('牛泽阳','张亚男'));

image-20220520160256797

5.3.表子查询案例二

查询出入职日期是2019-02-05之后的新入职人员信息,以及部门信息。

思路:首先查询出2019-02-05之后入职的人员信息,通过表子查询的方式嵌套这条SQL语句,将查询结果看做是一张新表,然后与部门表进行左外连接查询。

1)首先查询出2019-02-05之后入职的人员信息。

select * from ryxxb where rzsj > '2019-02-5';

image-20220520160854767

此时就可以把结果集当做是一张新表了。

2)将查询的SQL作为嵌套SQL,放在FROM之后,充当表1,然后把部门表充当表2,通过左外连接的方式查询出人员对应的部门名称。

select ry.*,bm.* from (select * from ryxxb where rzsj > '2019-02-5') as ry left join bmxxb as bm on ry.bm_id = bm.id; 

查询结果如下,对应的人员信息以及部门信息都显示了出来。

image-20220520161441713

5.4.表子查询案例三

查询出人员信息表的所有数据,然后写入到员工信息表

思路:通过子查询查询出每一条的记录,然后由INSERT写入新表。

insert into ygxxb (select * from ryxxb);

数据成功写入。

猜你喜欢

转载自blog.csdn.net/weixin_44953658/article/details/127295711