MySQL—— 连接查询
Posted 大彤小忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL—— 连接查询相关的知识,希望对你有一定的参考价值。
8. 连接查询
8.1 distinct
distinct
:把查询结果去除重复记录。注意:原表数据不会被修改,只是查询结果去重。
distinct
只能出现在所有字段的最前方:select distinct job from emp;
。
select ename,distinct job from emp;
会报错。
distinct
出现在job,deptno
两个字段之前,表示两个字段联合起来去重:select distinct job,deptno from emp;
。
- 统计一下工作岗位的数量:
select count(distinct job) from emp;
8.2 什么是连接查询
从一张表中单独查询,称为单表查询。
emp表和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取部门名字。这种跨表查询,多张表联合起来查询数据,被称为连接查询。
8.3 连接查询的分类
-
根据语法的年代分类:
SQL92:1992年的时候出现的语法
SQL99:1999年的时候出现的语法(重点) -
根据表连接的方式分类:
⋄ \\diamond ⋄ 内连接:
等值连接
非等值连接
自连接
⋄ \\diamond ⋄ 外连接:
左外连接(左连接)
右外连接(右连接)
⋄ \\diamond ⋄ 全连接
8.4 笛卡尔积现象
问题: 当两张表进行连接查询时,没有任何条件的限制会发生什么现象?
- 查询每个员工所在部门名称
从员工信息表查询员工姓名和部门编号:select ename,deptno from emp;
从部门信息表查询所有信息:select * from dept;
查询每个员工所在部门名称:select ename, dname from emp, dept;
(两张表连接没有任何条件限制)
一共14 * 4 = 56条记录。
当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象。
怎么避免笛卡尔积现象?连接时加条件,满足这个条件的记录被筛选出来!
- 当员工信息表的部门编号和部门信息表的部门编号相等时,查询每个员工所在部门名称:
select
emp.ename, dept.dname
from
emp, dept
where
emp.deptno = dept.deptno;
表起别名很重要,可以提高效率。
select
e.ename,d.dname
from
emp e, dept d
where
e.deptno = d.deptno; //SQL92语法
思考: 最终查询的结果条数是14条,但是匹配的过程中,匹配的次数减少了吗?
没有,还是56次,只不过进行了四选一,次数没有减少。
注意: 通过笛卡尔积现象得出,表的连接次数越多,效率越低,所以要尽量避免表的连接次数。
以上加入指定条件的查询也称为 “内连接”,只查询相等的数据(连接条件相等的数据)。
8.5 内连接
8.5.1 等值连接
等值连接: 条件是等量关系。
- 查询每个员工所在部门名称,显示员工名和部门名
emp e
和dept d
表进行连接,条件是:e.deptno = d.deptno
- SQL92语法:
select
e.ename,d.dname
from
emp e, dept d
where
e.deptno = d.deptno;
SQL92的缺点:结构不清晰,表的连接条件和后期进一步筛选的条件,都放到了where
后面。
- SQL99语法:
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno;
也可以写成如下形式:
select
e.ename,d.dname
from
emp e
inner join //inner可以省略(带着inner可读性更好!!!一眼就能看出来是内连接)
dept d
on
e.deptno = d.deptno; // 条件是等量关系,所以被称为等值连接。
SQL99的优点:表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where
。
SQL99的语法:
select
...
from
a
join
b
on
a和b的连接条件
where
筛选条件
SQL92 语法和 SQL99 语法的区别:99 语法可以做到表的连接和查询条件分离,特别是多个表进行连接的时候,会比SQL92更清晰。
8.5.2 非等值连接
非等值连接: 条件不是一个等量关系。
- 找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级
查询员工信息表所有信息:select * from emp;
查询薪水等级信息表所有信息:select * from salgrade;
找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级:
select
e.ename, e.sal, s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal; // 条件不是一个等量关系,称为非等值连接。
8.5.3 自连接
- 查询员工的上级领导,要求显示员工名和对应的领导名
查询员工信息表的员工编号、员工姓名、上级领导编号信息:select empno,ename,mgr from emp;
技巧: 一张表看成两张表。
emp a
员工表
emp b
领导表
查询员工的上级领导,要求显示员工名和对应的领导名:
select
a.ename as '员工名', b.ename as '领导名'
from
emp a
join
emp b
on
a.mgr = b.empno; //员工的领导编号 = 领导的员工编号
以上称为“自连接”,只有一张表连接,具体的查询方法,把一张表看作两张表即可,如以上示例:第一个表 emp a
代表了员工表,emp b
代表了领导表,相当于员工表和部门表一样。
8.6 外连接
查询员工信息表所有信息:select * from emp;
查询部门信息表所有信息:select * from dept;
内连接: A和B连接,AB两张表没有主次关系,是平等的。
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno; //内连接的特点:完成能够匹配上这个条件的数据查询出来。
8.6.1 右外连接
外连接(右外连接):
select
e.ename,d.dname
from
emp e
right join
dept d
on
e.deptno = d.deptno;
也可以写成如下形式:
// outer是可以省略的,带着可读性强。
select
e.ename,d.dname
from
emp e
right outer join
dept d
on
e.deptno = d.deptno;
right
代表什么:表示将join
关键字右边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表。
在外连接当中,两张表连接,产生了主次关系。
8.6.2 左外连接
外连接(左外连接):
select
e.ename,d.dname
from
dept d
left join
emp e
on
e.deptno = d.deptno;
也可以写成如下形式:
// outer是可以省略的,带着可读性强。
select
e.ename,d.dname
from
dept d
left outer join
emp e
on
e.deptno = d.deptno;
带有right
的是右外连接,又叫做右连接。
带有left
的是左外连接,又叫做左连接。
任何一个右连接都有左连接的写法,任何一个左连接都有右连接的写法。
左外连接(左连接)和右外连接(右连接)的区别:左连接以左面的表为准和右边的表比较,和左表相等的不相等都会显示出来,右表符合条件的显示,不符合条件的不显示;右连接恰恰相反。
思考: 外连接的查询结果条数一定是 >= 内连接的查询结果条数? 正确。
- 查询每个员工的上级领导,要求显示所有员工的名字和领导名:
select
a.ename as '员工名', b.ename as '领导名'
from
emp a
left join
emp b
on
a.mgr = b.empno;
8.7 三张表、四张表怎么连接
语法:
select
...
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
right join
d
on
a和d的连接条件
一条SQL中内连接和外连接可以混合,都可以出现!
- 找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级:
select
e.ename,e.sal,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno = d.deptno // e表和d表的连接条件:e表的员工部门编号要等于d表的部门编号
join
salgrade s
on
e.sal between s.losal and s.hisal; // e表和s表的连接条件:e表的员工薪资要在s表的losal值和hisal值之间
- 找出每个员工的部门名称以及工资等级还有上级领导,要求显示员工名、领导名、部门名、薪资、薪资等级:
select
e.ename,e.sal,d.dname,s.grade,l.ename
from
emp e
join
dept d
on
e.deptno = d.deptno // e表和d表的连接条件:e表的员工部门编号要等于d表的部门编号
join
salgrade s
on
e.sal between s.losal and s.hisal // e表和s表的连接条件:e表的员工薪资要在s表的losal值和hisal值之间
left join //要求找出每个员工的部门名称以及工资等级,捎带找出上级领导,所以前面的是主表,使用左外连接
emp l
on
e.mgr = l.empno; //e表和l表的连接条件:e表的领导编号 = l表的员工编号
以上是关于MySQL—— 连接查询的主要内容,如果未能解决你的问题,请参考以下文章