【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询

这篇具有很好参考价值的文章主要介绍了【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

「前言」文章内容大致是对MySQL复合查询的学习。

「归属专栏」MySQL

「主页链接」个人主页

「笔者」枫叶先生(fy)

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

一、基本查询回顾

前面篇章讲解的mysql表的查询都是对一张表进行查询,在实际开发中这远远不够,下面将讲解复合查询,首先回顾一下基本的查询。

使用的数据库是之前篇章的雇员信息表,员工表(emp)、部门表(dept)和工资等级表(salgrade)
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

mysql> select * from emp where (sal > 500 or job = 'MANAGER') and ename like 'J%';

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

mysql> select * from emp order by deptno asc, sal desc;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

使用年薪进行降序排序

mysql> select ename, sal*12+ifnull(comm, 0) as 年薪 from emp order by 年薪 desc;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
注:

  • 由于NULL与任何值做计算得到的结果都是NULL,因此在计算年薪时不能直接用月薪的12倍加上每个员工的奖金,这样可能导致得到的年薪为NULL值。
  • 在计算每个员工的年薪时,应该通过ifnull函数判断员工的奖金是否为NULL,如果不为NULL则ifnull函数返回员工的奖金,如果为NULL则ifnull函数返回0,避免让NULL值参与计算

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

解决该问题需要进行两次查询
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
此外,这种问题还可以使用子查询,将两句查询语句合并起来,需要将第一次查询的SQL语句用括号括起来。

mysql> select ename, job from emp where sal = (select max(sal) from emp);

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

也是使用子查询解决

mysql> select * from emp where sal > (select avg(sal) from emp);

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

在group by子句中指明按照部门号进行分组,在select语句中使用avg函数和max函数,分别查询每个部门的平均工资和最高工资

mysql> select deptno, format(avg(sal), 2) 平均, max(sal) 最高 from emp group by deptno;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

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

mysql> select deptno, avg(sal) 平均工资 from emp group by deptno having 平均工资 < 2000;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

mysql> select job, count(*) 人数, format(avg(sal), 2) 平均工资 from emp group by job;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

二、多表查询

上面的基础查询都是在一张表的基础上进行的查询,实际开发中往往数据来自不同的表,所以需要多表查询。

  • 在进行多表查询时,只需要将多张表的表名依次放到from子句之后,用逗号隔开即可,这时MySQL将会对给定的这多张表取笛卡尔积,作为多表查询的初始数据源
  • 多表查询的本质,就是对给定的多张表取笛卡尔积,然后在产生的新表进行查询

笛卡尔积是指给定两个集合A和B,其中A中的每个元素和B中的每个元素都可以组成一个有序对,这些有序对的集合就是A和B的笛卡尔积。

例如,员工表和部门表进行笛卡尔积

员工表:
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
部门表:
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
两张表进行笛卡尔积

mysql> select * from emp, dept;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
员工表和部门表的笛卡尔积由两部分组成,前半部分是员工表的列信息,后半部分是部门表的列信息
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
对员工表和部门表取笛卡尔积时,会先从员工表中选出一条记录与部门表中的所有记录进行组合,然后再从员工表中选出一条记录与部门表中的所有记录进行组合,以此类推,最终得到一张新表
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
对多张表取笛卡尔积后得到的数据并不都是有意义的。

比如对员工表和部门表取笛卡尔积时,员工表中的每一个员工信息都会和部门表中的每一个部门信息进行组合,而实际一个员工只有和自己所在的部门信息进行组合才是有意义的,因此需要从笛卡尔积产生的新表筛选出员工的部门号和部门的编号相等记录。
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
注意:进行笛卡尔积的多张表中可能会存在相同的列名,这时在选中列名时需要通过表名.列名的方式进行指明,如果有重复的不指明确切一列,就会报错。
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

显示雇员名、雇员工资以及所在部门的名字

从题意可以看出,部门名只有dept表中才有,其他数据来源于emp表,即数据来自EMP和DEPT表,因此要联合查询,即多表查询

mysql> select emp.ename, emp.sal, dept.deptno from emp, dept where emp.deptno = dept.deptno;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

部门名只有部门表中才有,员工名和员工工资只有员工表中才有,因此需要同时使用员工表和部门表进行多表查询,在where子句中指明筛选条件为员工的部门号等于部门编号(筛选符合条件的信息)

mysql> select ename, sal, emp.deptno, dname from emp, dept where emp.deptno = dept.deptno and dept.deptno = 10;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
注意:在筛选部门号等于10的部门时,可以使用员工表中的部门号,也可以使用部门表中的部门编号,因为两列都是一样的。

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

员工名和工资只有员工表中才有,而工资级别只有工资等级表中才有,因此需要同时使用员工表和工资等级表进行多表查询,在where子句中指明筛选条件为员工的工资在losal和hisal之间的记录

mysql> select ename, sal, grade from emp, salgrade where sal between losal and hisal;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

三、自连接

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

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

可以使用子查询,先对员工表进行查询得到FORD的领导的编号,然后再根据领导的编号对员工表进行查询得到FORD领导的姓名

mysql> select empno, ename from emp where empno = (select mgr from emp where ename = 'FORD');

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
也可以使用多表查询(自查询),因为员工表中的mgr字段能够将表中员工的信息和员工领导的信息关联起来。

mysql> select leader.empno, leader.ename from emp leader, emp worder where leader.empno = worder.mgr and worder.ename = 'FORD';

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
由于自连接是对同一张表取笛卡尔积,因此在自连接时至少需要给一张表取别名,否则无法区分这两张表中的列。

四、子查询

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

4.1 单行子查询

单行子查询,是指返回单行单列数据的子查询

显示SMITH同一部门的员工

在子查询中查询SMITH所在的部门号,在where子句中指明筛选条件为员工部门号等于子查询返回的部门号

mysql> select * from emp where deptno = (select deptno from emp where ename = 'SMITH');

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
此外,解决该问题也可以使用自连接

4.2 多行子查询

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

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

先查询10号部门有哪些工作岗位,在查询时要对结果进行去重,因为10号部门的某些员工的工作岗位可能是相同的
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
然后将上述查询作为子查询,在查询员工表时在where子句中使用in关键字,in关键字用于判断员工的工作岗位是子查询得到的若干岗位中的一个


mysql> select ename, job, deptno from emp 
    -> where job in (select distinct job from emp where deptno=10) and deptno<>10;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

先查询30号部门员工的工资,进行去重
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

将上述查询作为子查询,在查询员工表时在where子句中使用all关键字,all关键字用于判断员工的工资是否高于子查询得到的所有工资

mysql> select ename, sal, deptno from emp where sal > all(select distinct sal from emp where deptno=20);

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

使用any关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)

先查询30号部门员工的工资,然后在查询员工表时在where子句中使用any关键字,判断员工的工资是否高于子查询的得到的工资中的某一个

mysql> select ename, sal, deptno from emp where sal > any(select distinct sal from emp where deptno=30);

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

4.3 多列子查询

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

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

先查询SMITH所在部门的部门号和他的岗位,然后将上述查询作为子查询

mysql> select * from emp where (deptno,job) = (select deptno, job from emp where ename = 'SMITH') and ename <> 'SMITH';

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
注:

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

4.4 在from子句中使用子查询

  • 子查询语句不仅可以出现在where子句中,也可以出现在from子句中
  • 子查询语句出现from子句中,其查询结果将会被当作一个临时表使用

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

先查询每个部门的平均工资,这张表当做临时表使用
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
然后对员工表和上述的查询结果进行多表查询,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资大于临时表中的平均工资

mysql> select ename, emp.deptno, sal, 平均工资 from emp, (select deptno, avg(sal) 平均工资 from emp group by deptno) tmp 
    -> where emp.deptno=tmp.deptno and sal > 平均工资;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
注意:在from子句中使用子查询时,必须给子查询得到的临时表取一个别名,否则查询将会出错

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

先查询每个部门的最高工资
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
然后对员工表和上述的查询结果进行取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资等于临时表中的最高工资

mysql> select ename, sal, emp.deptno, 最高工资 from emp, (select max(sal) 最高工资, deptno from emp group by deptno) tmp 
    ->  where emp.deptno=tmp.deptno and sal=最高工资;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

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

按照部门号进行分组,分别查询每个部门的人员数量
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号即可

mysql> select dname, dept.deptno, loc, 部门人数 from dept, (select deptno, count(*) 部门人数 from emp group by deptno) 
    -> tmp where dept.deptno = tmp.deptno;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
上述也可以只使用多表查询解决

mysql> select dname, dept.deptno, loc, count(*) 人数 from emp, dept 
    -> where emp.deptno = dept.deptno 
    -> group by dept.deptno, dname, loc;

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android

五、合并查询

合并查询,是指将多个查询结果进行合并,关键字unionunion all

  • union用于取得两个查询结果的并集,union会自动去掉结果集中的重复行
  • union all也用于取得两个查询结果的并集,但union all不会去掉结果集中的重复行

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

查询工资大于2500的员工,查询职位是MANAGER的员工
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
可以使用or操作符将where子句中的两个条件关联起来
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
也可以使用union将上述的两条查询SQL连接起来,这时将会得到两次查询结果的并集,并且会对合并后的结果进行去重

mysql> select ename, job, sal from emp where sal > 2500 union
    -> select ename, job, sal from emp where sal > 2500 or job = 'MANAGER';

【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
可以使用union all,结果是不去重
【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询,MySQL,mysql,学习,android
注意:待合并的两个查询结果的列的数量必须一致,否则无法合并
--------------------- END ----------------------文章来源地址https://www.toymoban.com/news/detail-673319.html

「 作者 」 枫叶先生
「 更新 」 2023.8.25
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。

到了这里,关于【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL ——多表连接查询

    内连接 : 假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来。A和B两张表没有主付之分,两张表是平等的。 :inner join on 语句:select * from a_table a inner join b_table b on a.a_id = b.b_id; 说明:组合两个表中的记录,返回关联字段相符的记录,也就

    2024年04月16日
    浏览(55)
  • MySQL每日一练:多表查询——连接查询、子查询

    目录 1、首先创建员工表emp和部门表dept: dept表: emp表:  2、插入数据: dept表: emp表: 3、 按条件查找 dept表: emp表:  dept表: emp表: 1.找出销售部门中年纪最大的员工的姓名  2.求财务部门最低工资的员工姓名  3.列出每个部门收入总和高于8000的部门名称   4.求工资在

    2024年02月15日
    浏览(37)
  • MySQL单表查询与多表连接查询

    单表查询 创建数据表emp 插入数据 -- 1. 查询出部门编号为30的所有员工 -- 2. 所有销售员的姓名、编号和部门编号。 -- 3. 找出奖金高于工资的员工。 -- 4. 找出奖金高于工资60%的员工。 -- 5. 找出部门编号为10中所有经理,和部门编号为20中所有销售员的详细资料。 -- 6. 找出部门

    2024年02月13日
    浏览(43)
  • MySQL每日一练:多表查询——连接查询、子查询(1)

    目录 1、首先创建员工表emp和部门表dept: dept表: emp表:  2、插入数据: dept表: emp表: 3、 按条件查找 dept表: emp表:  dept表: emp表: 1.找出销售部门中年纪最大的员工的姓名  2.求财务部门最低工资的员工姓名  3.列出每个部门收入总和高于8000的部门名称   4.求工资在

    2024年02月15日
    浏览(37)
  • ⑧【MySQL】数据库查询:内连接、外连接、自连接、子查询、多表查询

    个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 多表关系 : 一对一 :在 任意一方 加入外键,关联另一方的主键,并设置外键为唯一(UNIQUE)。 一对多(

    2024年02月05日
    浏览(54)
  • 【MySQL学习】MySQL表的复合查询

    对MySQL表的基本查询还远远达不到实际开发过程中的需求,因此还需要掌握对数据库表的复合查询。本文介绍了多表查询、子查询、自连接、内外连接等复合查询的案例。 来自oracle 9i的经典测试表: emp员工表 dept部门表 salgrade工资等级表 MySQL表的基本查询都是针对一张表进行

    2024年02月03日
    浏览(36)
  • MySQL---多表联合查询(上)(多表关系、外键约束、学生成绩多表关系、交叉连接查询)

    1. 多表关系 MySQL 多表之间的关系可以概括为: 一对一:        比如:一个学生只有一张身份证;一张身份证只能对应一学生。        实现原则:在任一表中添加唯一外键,指向另一方主键,确保一对一关系。         一般一对一关系很少见,遇到一对一关系的表最好是

    2024年02月05日
    浏览(55)
  • 【MYSQL】聚合函数和单表/多表查询练习、子查询、内外连接

    目录 1.聚合函数 1.1.group by子句 1.2.having语句 2.单表查询  2.2单表查询 3.多表查询  3.2.子查询 5.内链接 6.外连接 函数 说明 count 返回查询到的数据的数量 sum 返回查询到的数据的总和 avg 返回查询到的数据的平均值 max 返回查询到的数据的最大值 min 返回查询到的数据的最小值

    2024年02月04日
    浏览(48)
  • 【从删库到跑路】MySQL数据库的查询(单表查询,多表查询,内外连接,联合查询,子查询)

    🎊专栏【MySQL】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 在项目开发中,在进行数据库表结构设计时,会根据业务需求以及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联

    2024年02月10日
    浏览(48)
  • MySQL---多表联合查询(下)(内连接查询、外连接查询、子查询(ALL/ANY/SOME/IN/EXISTS关键字)、自关联查询)

    1. 内连接查询 数据准备: 内连接查询语法: 2. 外连接查询 语法: 左外连接: left outer join:             select * from A left outer join B on 条件 ;             右外连接: right outer join:             select * from A right outer join B on 条件 ;             满外连接 : full out

    2024年02月04日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包