MySQL——复合查询

1. 基本查询回顾

这里我们还是使用之前的那三张表;

查询工资高于500或岗位为MANAGER的员工,同时要求员工姓名的首字母为大写的J

查询员工信息,按部门号升序而员工工资降序显示

查询员工信息,按年薪降序显示

这里需要注意的就是奖金(comm)可能为NULL,MySQL中NULL是不参与运算的,所以这就可能导致最终年薪为NULL的情况,这时就需要使用ifnull函数来判断一下。

查询工资最高的员工的姓名和岗位

这个问题我们可以分两步来进行,首先我们找出最高工资,然后在根据查出来的结果去查询对应的员工信息。

但是这种写法我们并不推荐,这里我们可以使用子查询,将两条SQL变成一条SQL;

查询工资高于平均工资的员工信息

查询每个部门的平均工资和最高工资

查询每种岗位的雇员总数和平均工资

2. 多表查询

之前我们所有的查询都是在一张表中进行的单表查询,实际开发环境下,我们更多地需要进行多表查询,多表查询的本质,就是对给定的多张表取笛卡尔积,然后在笛卡尔积中进行查询。

我们可以认为MySQL中一切皆表,我们做笛卡尔积后得到的是一张"新表",本质上我们还是在进行单表查询。

显示部门号为10的部门名、员工名和员工工资

这里我们首先要分析需求,看看需要显示的都在哪些表中,在这里部门名这个信息在部门表中,而其他信息在员工表中,所以我们需要将两张表联系起来,然后再进行条件筛选,因为做完笛卡尔积后会产生一些无效数据,我们要将无效数据剔除。

显示各个员工的姓名、工资和工资级别

这里还是与上一题的思路一样,我们需要找出题目需求来自于哪些表,这里的工资等级来自于工资表,其他信息来自于员工表,那么我们就需要将员工表和工资表进行笛卡尔积,然后进行条件筛选。

3. 自连接

自连接是指在同一张表进行连接查询,也就是说我们不仅可以取不同表的笛卡尔积,也可以对同一张表取笛卡尔积。

显示员工FORD的上级领导的编号和姓名

解决该问题可以使用子查询,先对员工表进行查询得到FORD的领导的编号,然后再根据领导的编号对员工表进行查询得到FORD领导的姓名。如下:

此外,解决该问题也可以使用自连接,因为员工表中的mgr字段能够将表中员工的信息和员工领导的信息关联起来。如下:

说明一下: 由于自连接是对同一张表取笛卡尔积,因此在自连接时至少需要给一张表取别名,否则无法区分这两张表中的列。

4. 子查询

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

4.1 单行子查询

返回单行单列数据的子查询。

显示SMITH同一部门的员工信息

4.2 多行子查询

返回多行单列数据的子查询

in关键字:显示和10号部门的工作岗位相同的员工的名字、岗位、工资和部门号,但是不包含10号部门的员工

先查询10号部门有哪些工作岗位,在查询时最好对结果进行去重,因为10号部门的某些员工的工作岗位可能是相同的。如下:

然后我们需要利用上面子查询得到的结果来进一步查询,这里就需要用到in关键字,判断员工的工作岗位是子查询得到的若干岗位中的一个,如果是则符合筛选条件,由于要求筛选出来的员工不包含10号部门的,因此还需要在where子句中指明筛选条件为部门号不等于10。如下:

all关键字:显示工资比30号部门的所有员工的工资高的员工的姓名、工资和部门号

先查询30号部门员工的工资,在查询时最好对结果进行去重,因为30号部门的某些员工的工资可能是相同的。如下:

然后将上述查询作为子查询,在查询员工表时在where子句中使用all关键字,判断员工的工资是否高于子查询得到的所有工资,如果是则符合筛选条件。如下:

本题其实可以等价于求工资高于30号部门的最高工资的员工,可以使用单行子查询来解决;

any关键字:显示工资比30号部门的任意员工的工资高的员工的姓名、工资和部门号,包含30号部门的员工

先查询30号部门员工的工资,然后在查询员工表时在where子句中使用any关键字,判断员工的工资是否高于子查询的得到的工资中的某一个,如果是则符合筛选条件。如下:

但实际这道题也等价于找到工资高于30号部门的最低工资的员工,因此也可以使用单行子查询得到30号部门的最低工资,然后判断员工的工资是否高于子查询得到的最低工资即可,由于要求筛选出来的员工包含30号部门的,因此不需要再对部门号进行过滤。如下:

4.3 多列子查询

返回多列数据的子查询。

显示和SMITH的部门和岗位完全相同的员工信息,不包含SMITH本人

先查询SMITH所在部门的部门号和他的岗位。如下:

然后将上述查询作为子查询,在查询员工表时在where子句中,指明筛选条件为部门号和岗位等于子查询得到的部门号和岗位,并且员工的姓名不为SMITH即可。如下:

说明一下:

  • 多列子查询得到的结果是多列数据,在比较多列数据时需要将待比较的多个列用圆括号括起来。
  • 多列子查询返回的如果是多行数据,在筛选数据时也可以使用in、all和any关键字。

4.4 在from子句中使用子查询

子查询语句出现from子句中,其查询结果将会被当作一个临时表使用。

显示每个高于自己部门平均工资的员工的姓名、部门、工资和部门的平均工资

首先查询每个部门的平均工资。如下:

由于显示信息中包含部门的平均工资,需要同时使用员工表和上述的查询结果进行多表查询,这时可以将上述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资大于临时表中的平均工资。如下:

说明一下: 在from子句中使用子查询时,必须给子查询得到的临时表取一个别名,否则查询将会出错。

显示每个部门工资最高的员工的姓名、工资、部门和部门的最高工资

先查询每个部门的最高工资。如下:

将上述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资等于临时表中的最高工资。如下:

显示每个部门的部门名、部门编号、所在地址和人员数量

在group by子句中指明按照部门号进行分组,分别查询每个部门的人员数量。如下:

将上述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号即可。如下:

相关推荐
0xDevNull4 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希5 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神5 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员5 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴5 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存