MySQL复合查询

目录

  • 基本查询回顾
  • 多表查询
  • 自连接
  • 子查询
    • 单行子查询
    • 多行子查询
    • 多列子查询
    • 在from子句中使用子查询

基本查询回顾

给出三张表,分别是员工表(emp)、部门表(dept)和工资等级表(salgrade)。

员工表(emp)中包含如下字段:

  • 雇员编号(empno)。
  • 雇员姓名(ename)。
  • 雇员职位(job)。
  • 雇员领导编号(mgr)。
  • 雇佣时间(hiredate)。
  • 工资月薪(sal)。
  • 奖金(comm)。
  • 部门编号(deptno)。

部门表(dept)中包含如下字段:

  • 部门编号(deptno)。
  • 部门名称(dname)。
  • 部门所在地点(loc)。

工资等级表(salgrade)中包含如下字段:

  • 等级(grade)。
  • 此等级最低工资(losal)。
  • 此等级最高工资(hisal)。

员工表(emp)中的内容如下:

MySQL复合查询_第1张图片

部门表(dept)中的内容如下:

MySQL复合查询_第2张图片

工资等级表(salgrade)中的内容如下:

MySQL复合查询_第3张图片

查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J

首先我们需要在wher子句中指明筛选条件工资高于500或岗位为MANAGER的雇员, 然后通过模糊匹配指明员工姓名首字母为大写的J,最后指明要查询的为姓名,工资,岗位。

MySQL复合查询_第4张图片

按照部门号升序而雇员的工资降序排序

在select语句中指明要查询的姓名,工资, 部门,然后使用order by子句依次指明按部门号排升序和按员工工资排降序。

MySQL复合查询_第5张图片

使用年薪进行降序排序

首先在select语句中指明姓名, 年薪,由于年薪还存在奖金的问题,所以在这儿我们可以使用ifnull函数来进行判断,然后再根据年薪进行排序。

MySQL复合查询_第6张图片

显示工资最高的员工的名字和工作岗位

这个案例需要经过两次查询,首先,我们需要找出工资最高的员工。

MySQL复合查询_第7张图片

然后我们使用where子句判断工资=最高工资的员工,然后在select语句中指明姓名和工作岗位。

MySQL复合查询_第8张图片

当然,我们也可以将两个SQL合并成一个语句。

MySQL复合查询_第9张图片

显示工资高于平均工资的员工信息

首先我们的计算出平均工资,然后再使用where子句来判断工资高于平均工资的员工,最后select语句后指明员工姓名,工资。

MySQL复合查询_第10张图片

显示每个部门的平均工资和最高工资

我们可以直接在select语句后指明平均工资和最高工资,然后结合group by子句指定按部门进行分组。

MySQL复合查询_第11张图片

显示平均工资低于2000的部门号和它的平均工资

在group by子句中指明按照部门号进行分组,在select语句中使用avg函数查询每个部门的平均工资,在having子句中指明筛选条件为平均工资小于2000。
MySQL复合查询_第12张图片

显示每种岗位的雇员总数,平均工资

先在group by子句中指定按照岗位分组,然后再select语句中依次指明岗位,雇员总数和平均工资。

MySQL复合查询_第13张图片

多表查询

  • 上面的基础查询都是在一张表的基础上进行的查询,而实际开发中往往需要将多张表关联起来进行查询,这就叫做多表查询。
  • 在进行多表查询时,只需要将多张表的表名依次放到from子句之后,用逗号隔开即可,这时MySQL将会对给定的这多张表取笛卡尔积,作为多表查询的初始数据源。
  • 多表查询的本质,就是对给定的多张表取笛卡尔积,然后在笛卡尔积中进行查询。

所谓的对多张表取笛卡尔积,就是得到这多张表的记录的所有可能有序对组成的集合,比如下面对员工表和部门表进行多表查询,由于查询语句中没有指明筛选条件,因此最终得到的结果便是员工表和部门表的笛卡尔积。

MySQL复合查询_第14张图片

注意:

  • 员工表和部门表的笛卡尔积由两部分组成,前半部分是员工表的列信息,后半部分是部门表的列信息。
  • 对员工表和部门表取笛卡尔积时,会先从员工表中选出一条记录与部门表中的所有记录进行组合,然后再从员工表中选出一条记录与部门表中的所有记录进行组合,以此类推,最终得到的就是这两张表的笛卡尔积。

需要注意的是,对多张表取笛卡尔积后得到的数据并不都是有意义的,比如对员工表和部门表取笛卡尔积时,员工表中的每一个员工信息都会和部门表中的每一个部门信息进行组合,而实际一个员工只有和自己所在的部门信息进行组合才是有意义的,因此需要从笛卡尔积中筛选出员工的部门号和部门的编号相等记录。

MySQL复合查询_第15张图片

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

由于部门名和员工名在两个不同的表中,所以我们在这儿要使用到多表查询,在where子句中指明筛选条件为员工的部门号等于部门编号,并且部门号为10的记录。

MySQL复合查询_第16张图片

注意:第一个筛选条件已经筛选出员工的部门号和部门编号相等的记录,因此在筛选部门号等于10的部门时,可以使用员工表中的部门号,也可以使用部门表中的部门编号。

显示各个员工的姓名,工资,及工资级别

姓名和工资在员工表中,工资级别在工资等级表中,因此需要使用复合查询,在where子句中指明筛选条件工资是处于losal和hisal之间的。

MySQL复合查询_第17张图片

自连接

  • 自连接是指在同一张表进行连接查询,也就是说我们不仅可以取不同表的笛卡尔积,也可以对同一张表取笛卡尔积。
  • 如果一张表中的某个字段能够将表中的多条记录关联起来,那么就可以通过自连接将表中通过该字段关联的记录组合起来。

显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号–empno)

首先我们使用子查询,先将查询得到FORD的上级领导的编号,然后再使用where子句根据领导的编号对员工表进行查询找到FORD领导的姓名。

MySQL复合查询_第18张图片

同样,我们也可以使用自连接的方法,对员工表进行自连接以后,我们可以先筛选出员工领导编号等于领导编号信息,然后再进一步指明筛选员工的姓名为FORD。

MySQL复合查询_第19张图片

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

子查询

  • 子查询是指嵌入在其他SQL语句中的查询语句,也叫嵌套查询。
  • 子查询可分为单行子查询、多行子查询、多列子查询,以及在from子句中使用的子查询。

单行子查询

单行子查询,返回一行记录的子查询。

显示SMITH同一部门的员工

首先在子查询中找到SMITH的部门号,然后使用where子句筛选员工部门号等于子查询的部门号,并且不包括SMITH。

MySQL复合查询_第20张图片

多行子查询

多行子查询,返回多行记录的子查询。

in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自
己的

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

MySQL复合查询_第21张图片

然后将上述查询作为子查询,在查询员工表时在where子句中使用in关键字,判断员工的工作岗位是子查询得到的若干岗位中的一个,如果是则符合筛选条件,由于要求筛选出来的员工不包含10号部门的,因此还需要在where子句中指明筛选条件为部门号不等于10。

MySQL复合查询_第22张图片

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

先查询30号部门员工的工资,在查询时最好对结果进行去重,因为30号部门的某些员工的工资可能是相同的,然后将上述查询作为子查询,在查询员工表时在where子句中使用all关键字,判断员工的工资是否高于子查询得到的所有工资,如果是则符合筛选条件。

MySQL复合查询_第23张图片

这道题也等价于找到工资高于30号部门的最高工资的员工,因此也可以使用单行子查询得到30号部门的最高工资,然后判断员工的工资是否高于子查询得到的最高工资即可。

MySQL复合查询_第24张图片

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

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

MySQL复合查询_第25张图片

这道题也等价于找到工资高于30号部门的最低工资的员工,因此也可以使用单行子查询得到30号部门的最低工资,然后判断员工的工资是否高于子查询得到的最低工资即可。

MySQL复合查询_第26张图片

多列子查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言
的,而多列子查询则是指查询返回多个列数据的子查询语句

查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人

首先我们需要找到SMITH所在地部门和岗位。

MySQL复合查询_第27张图片

然后使用where子句筛选部门和岗位跟子查询部门和岗位完全相同的雇员,并且满足条件不是SMITH 。

MySQL复合查询_第28张图片

注意:

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

在from子句中使用子查询

子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

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

首先我们要找到每个部门的平均工资。

MySQL复合查询_第29张图片

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

MySQL复合查询_第30张图片

查找每个部门工资最高的人的姓名、工资、部门、最高工资

首先我们的找到每个部门的最高工资。

MySQL复合查询_第31张图片

然后我们将上述查询当做子查询放入到from子句中,然后对员工表和临时表取笛卡尔积,使用where子句筛选员工表中工资等于临时表中最高工资,并且员工表中部门号与临时表中部门号相等。

MySQL复合查询_第32张图片

显示每个部门的信息(部门名,编号,地址)和人员数量

  • 使用子查询

首先我们需要查询每个部门的人数。

MySQL复合查询_第33张图片

然后将上述查询作为from的子查询,对部门表和临时表取笛卡尔积,使用where子句筛选部门表中部门号与临时表中部门号相等。

MySQL复合查询_第34张图片

你可能感兴趣的:(MySQL,mysql,数据库)