MySQL 复合查询和内外连接 -- 子查询,多表查询,自连接,合并查询,表的内外连接

目录

1. 子查询

1.1 单行子查询

1.2 多行子查询

1.3 多列子查询

1.4 在 from 子句中使用子查询

2. 多表查询

3. 自连接 

4. 合并查询

4.1 union

4.2 union all

5. 表的内连接

6. 表的外连接


        下列先给出该博客中所用到的所有表的数据。

        (1)部门表(dept)

        (2) 员工表(emp)

        (3) 薪资等级表(salgrade)

1. 子查询

        子查询是指嵌入在其他 sql 语句中的 select 语句,也叫嵌套查询。

1.1 单行子查询

        单行子查询:指的是在子查询语句中,返回的数据只有一行。-- 返回一个字段并且该字段只有一个值。

        例1:查询与 SMITH 同一个部门的员工

        如上图,MySQL 会先执行括号中的子语句,返回一个 ename = 'SMITH' 的部门号 deptno,然后再执行外部 select 语句,筛选部门号与 SMITH 相同的数据。 

1.2 多行子查询

        多行子查询:指的是在子查询语句中,返回的数据为多行。-- 返回一个字段并且该字段有多个值。

        (1)in 关键字:用于判断一个数据是否在某一个集合当中

        例1:查询和 10 号部门的工作岗位相同的员工名字,岗位,工资,部门号但是不包含 10 号部门自己的员工

        上述的查询可以这样理解,(1)查出 10 号部门有哪些岗位。(2)筛选出 emp 表中与 10 部门中岗位相同岗位的员工。(3)排除 10 号部门自己的员工。 

        上述的语句中,子查询到的 job 不只是一个值,所以被称为多行子查询。

        (2)all 关键字:用于在判断的时候所有数据都要满足条件。

        例2:查询工资比 30 号部门所有员工的工资高的员工的姓名、工资和部门号。

        上图中的做法是先找到 30 号部门中最高的工资,然后再筛选出大于最高工资的员工。

        而上述的做法是先筛选出 30 号部门中所有员工的工资,然后再次筛选大于 30 号部门中所有员工工资的其他员工。 

        (3)any 关键字:用于在判断时是否至少有一条数据满足条件。

        例3:显示工资比 30 号部门中至少一名员工工资高的员工的姓名、工资、和部门号(包含自己部门的员工)。

        换句话说,就是显示比 30 号部门中最低工资要高的员工。

        上图为先筛选出 30 号部门中最低工资,然后筛选大于最低工资的员工。

        而这个图是先筛选出 30 号部门所有员工的工资,然后判断的时候表示 sal 大于 30 号部门中任意一名员工的工资高即可。 

1.3 多列子查询

        多列子查询:子查询中返回的数据为多列。-- 返回多个字段,该字段可以有一个值也可以有多个值。其实上述例子中的情况为单列单行自查徐,单列多行子查询,所以多行和多列是不冲突的。

        例1:查询和 SMITH 的部门和岗位完全相同的其他员工

        上述的子查询可以称为多列单行子查询,先查出 SMITH 的部门号和岗位,在利用部门号和岗位筛选出员工,最后在筛选掉 SMITH 自己。 

1.4 在 from 子句中使用子查询

        上述所有的子查询都是在 where 子句中充当筛选条件。但是子查询也可以在 from 子句中使用,这里要清楚一个概念,任何时刻查询出来的临时数据,在逻辑上本质都可以当作一张表

        例1:显示每个部门中高于该部门平均工资的员工的姓名、部门、工资以及部门平均工资

        上图中先是将每个部门的部门号和部门平均工资筛选出来作为一张临时表,再将两张表作笛卡尔积,筛选出两张表中部门号相同且工资大于部门平均工资的员工信息。 

2. 多表查询

        如下图所示,得到的结果称为笛卡尔积,也就是两张表每条数据的两两组合

        其中有些数据是没有意义的,比如第一条数据,SMITH 是属于 20 号部门的,所有拼接上部门表中部门号为 10 的数据就不是一条合理的数据,可以利用两张表相同的字段(上图中的部门号)进行有意义的数据筛选

        例1:显示员工名、员工工资以及所在部门(不仅仅是部门号,还有部门信息)。则需要从 emp 表和 dept 表中得出数据,所以可以用以下查询语句进行查询:

        例2:显示各个员工的姓名、工资及工资级别。则需要从 emp 表和 salgrade 表中得到数据,可以通过员工工资在那个工资等级的范围内进行有效数据的筛选:

3. 自连接 

        自连接就是将两张相同的表作笛卡尔积。由于两张表的名字相同,所以作笛卡尔积的时候需要进行重命名

        如上两张图所示,当没有重命名对相同的表作笛卡尔积会报错,重命名之后作笛卡尔积就不会报错。 

        例1:显示员工 FORD 上级领导的编号和姓名(mgr 是员工领导的编号)。这个需求可以分为两步来进行,一是找打 FORD 上级领导的编号,二是使用这个编号找到领导的信息,而这些信息都在 emp 表中,所以语句如下:

        也可以将 emp 表先进行自连接,然后通过 FORD 上级领导编号 mgr 和员工编号 empno 相等的方式找到 FORD 上级领导的信息,语句如下:

4. 合并查询

4.1 union

        union:该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中重复的行

        例1:将工资大于 2500 或职位是 MANAGER 的人找出来

        上述是使用了两个筛选条件筛选出结果。 

        而上图是使用 union 将两个查询的结果集合并起来。 

4.2 union all

        union all:该操作符用于取得两个结果集的并集。但是该操作符不对结果集中重复行去重

        上述两种合并查询的时候列字段的个数和属性必须相同才能进行拼接。 

5. 表的内连接

        上述多表进行笛卡尔积之后都需要一个 where 语句进行有效数据的筛选,其实就叫做内连接,但是为了方便给其规定了一种内连接语法

select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;

        例1:显示 SMITH 的名字和部门名称

        上图为之前使用 where 子句的写法。

        这个是使用内连接语法的写法。 

6. 表的外连接

        (1)左外连接:在两张表进行笛卡尔积之后,左表的数据完全显示

select 字段 from 表名1 left join 表名2  on 连接条件;

        如上图所示,现在有两张表,一个学生表,一个成绩表,需要将学生表中的所有行数据筛选出来,就算学生没有成绩也需要筛选出来,这时候就可以使用左外连接

        (2)右外连接: 在两张表进行笛卡尔积之后,右表的数据完全显示

select 字段 from 表名1 right join 表名2  on 连接条件;

        现在需要将成绩表中所有行数据筛选出来,就算成绩没有对应的学生也要将右表的所有行进行显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值