MySQL中数据查询语言(DQL)多表查询

157 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

1、 DQL 数据查询

  • 从数据表中提取满意特定条件的记录
  • 单表查询, 在前面两篇文章中已经详细说明了,这里不再赘述
  • 多表查询

1.1 多表连查

  • 两张或者两张以上的表,通过某种条件连接在一起
  • 笛卡尔积:

    1. A表有m条记录,B表有n 条记录,结果n*m条
    2. 如果查询n张表,必须要指定n-1个公共条件,否则会产生笛卡尔积
  • SQL 语法 :
  1. SQL92 比较老
  2. SQL99 比较新
  • 注释: 这些知识点不好用语言描述,因此每说明一个知识点,都将用一个例题进行解释,例题所用的表均为以下三张表

  • 员工表 emp

emp表.png

  • 部门对照表 dept

部门对照表.png

  • 薪资等级表 : salgrade

工资等级表.png

2 连接方法

2.1内连接

  1. 连接方法: inner join on
  2. 两张表时⽤inner join连接查询之后⽣产的笛卡尔积数据中很多数据都是⽆意义的,我们 如何消除⽆意义的数据呢? —— 添加两张进⾏连接查询时的条件

例题: 查询员工对应的部门

select 
     e.ename '员工', d.dname '部门'
from  emp e join dept d 
​
on 
 e.deptno = d.deptno;
  • 1.2.2 非等值连接

例题: 查询员工工资等级 比如 : 张三 2 (张三的工资等级为2 )

 select 
 p.ename, s.grade
 
 from emp p join salgrade s 
 
 on p.sal between s.losal and s.hisal;
  • 1.2.3 自连接

自己连接自己,一张表相当于两张表使用

例题: 查询员工的领导,打印员工和领导的姓名

select 
 es.ename'领导',e.ename'员工'
 
 from emp e join emp es
 
 on e.mgr = es.empno;

注释: 这道题有点南想到,就是e.mgr = es.empno; 判断条件,我 是这么理解的,判断条件: 员工对应的领导编号 e.mgr 与领导编号 es.empno 相同,输出的是 es 为 领导,e 为员工, 各自的姓名 ,打印结果如下:

自连接-单表操作.png

2.2 外连接

使用频率高

2.2.1 左连接

关键字 left join

左连接:显示左表中的所有数据,如果在有右表中存在与左表记录满⾜匹配条件的数据,则 进⾏匹配;如果右表中不存在匹配数据,则显示为Null

例题: 查找员工的领导

   select
     es.ename' 领导',e.ename'员工'
    
     from emp e left out join  emp es
    
     on e.mgr = es.empno;
  • 左连接效果图

左连接.png

2.2.2 右连接

关键字 right join

例题: 查找员工的领导

   select
      es.ename' 领导',e.ename'员工'
    
      from emp e right join  emp es
    
      on e.mgr = es.empno;
  • 右连接效果图

右连接.png

2.2.3 补充-数据表别名

上面的案例已经使用了,这里补充一下

  1. 取别名的好处: 如果在连接查询的多张表中存在相同名字的字段,我们可以使⽤ 表名.字段名 来进⾏区 分,如果表名太⻓则不便于SQL语句的编写,我们可以使⽤数据表别名
  2. 使用: 查找员工的领导
   select
      es.ename' 领导',e.ename'员工'
    
      from emp e right join  emp es
    
      on e.mgr = es.empno;

这里的 e 和 es 就是别名,看上去简介,操作容易

3.子查询

⼦查询 — 先进⾏⼀次查询,第⼀次查询的结果作为第⼆次查询的源/条件(第⼆次查询 是基于第⼀次的查询结果来进⾏的)

3.1 where子查询

例题: 查询高于平均薪资的员工

select avg(sal) from emp;
 
 select e.ename,e.sal
 
 from emp e 
 
 where e.sal >((select avg(sal) from emp) );

3.2 from子查询

例题: 查询每个部门的平均工资和工资等级

    select 
    
    da.deptno, da.avg, s.grade
​
    from
​
        (select deptno,avg(sal) avg from emp group by deptno) da
​
    join
​
        salgrade s
​
    on
​
        da.avg between s.losal and s.hisal;

运行结果:

from子查询.png

3.3 select子查询

例题: 查询员工对应的部门,使用select子查询

select
    e.ename, (select dname from dept where e.deptno = dept.deptno) as dname
from 
    emp e;

select子查询.png

三张表查询例题

例题说明: 查询每一个员工的部门名称以及工资等级

思路: 先连接两张表,得到一张表,连第三张表

select 	
	e.ename, d.dname, s.grade	
from
	emp e
join
	dept d	
on	
	e.deptno = d.deptno
join
	salgrade s
on 
	e.sal between s.losal and s.hisal;

4.总结

多表连查,相比较单表,难度还是有的,不光是在一些指令上要能够熟悉运行,以后工作多表查询也是家常便饭,所以一定要学好,大部分情况使用多表查询就能满足日常的业务需求,子查询的效率相比多表查询低,但是有些问题只能使用子查询来解决,所以多表查询和子查询都是数据库必备的知识点

\