第三章 多表查询

第三章 多表查询

问题:如何查询员工的编号、姓名、薪水和部门编号、部门名称?

方法1:多条sql语句,先从员工表查询员工的编号、姓名、薪水,然后从部门表查询部门编号、部门名称。

方法2:单条sql语句查询

一、多表查询

1、交叉连接

​ 交叉连接查询:(笛卡尔积:两张表的所有情况全部组合在一起)

​ 缺点:没有实际意义,只有理论意义,让我们了解连接的原理

​ 语法:select * from 表1 join 表 2;

SELECT * FROM dept JOIN empolee;
2、自然连接

​ 会自动的匹配所有的同名列,并且同列名只保留一份。

​ 语法:select * from 表1 natural join 表2;

SELECT * FROM dept NATURAL JOIN empolee;

没有指定表名,NATURAL关键字会自动匹配

SELECT empno,ename,sal,dno,dname FROM dept NATURAL JOIN empolee;

指定表名,提升查询效率

SELECT empolee.empno,empolee.ename,empolee.sal,dept.dno,dept.dname FROM dept NATURAL JOIN empolee;

表名太长,给表起别名

SELECT e.empno,e.ename,e.sal,d.dno,d.dname FROM dept as d NATURAL JOIN empolee as e;
3、using子句

自然连接匹配的是全部同名列,using子句给定需要匹配的同名列,按照给定同名列进行匹配。

语法:select * from 表1 join 表2 using(同名列);

SELECT e.empno,e.ename,e.sal,d.dno,d.dname FROM dept AS d JOIN empolee AS e USING(dno);
-- USING(dno)等价于 e.dno = d.dno

缺点:using子句和自然连接必须有相同的列,如果两张表的主键,外键的名称不一样,就无法使用自然连接和using子句

4、on子句

on子句解决了以上的全部问题,选用on子句即可

SELECT e.empno,e.ename,e.sal,d.dno,d.dname FROM dept AS d JOIN empolee AS e on e.dno=d.dno;

语法:select * from 表1 join 表2 on( 条件);(条件一般是指表1和表2的限制条件)

以上的四种连接都属于内连接。

二、内连接和外连接

1、内连接:只是显示匹配的数据(笛卡尔积)
SELECT e.empno,e.ename,e.sal,d.dno,d.dname FROM dept AS d JOIN empolee AS e on (e.dno=d.dno);
2、外连接:可以显示部分或者全部匹配的数据
1)左外连接

left outer join还可以显示左表的未匹配的部分数据或者全部数据。

语法:select * from 表1 left outer join 表2 on (条件);

SELECT e.empno,e.ename,e.sal,d.dno,d.dname FROM dept AS d LEFT OUTER JOIN empolee AS e ON (e.dno=d.dno);
2)右外连接

right outer join还可以显示右表的未匹配的部分数据或者全部数据。

语法:select * from 表1 right outer join 表2 on (条件);

SELECT e.empno,e.ename,e.sal,d.dno,d.dname FROM dept AS d RIGHT OUTER JOIN empolee AS e ON (e.dno=d.dno);
3)全连接(mysql不支持,oracle支持)

full outer join还可以显示右表的未匹配的部分数据或者全部数据。

mysql解决方案:(左外连接+右外连接的并集)

select * from 表1 left outer join 表2 on (条件) union select * from 表1 right outer join 表2 on (条件);

备注:

union:去重(效率低)

union all:不去重(效率高)

三、三表查询

1、解决方案

双表查询——》单表——》双表查询

2、案例

问题:查询员工的编号、姓名、薪水(员工表);部门、部门名称(部门表);薪水等级(薪水等级)。

select e.empno,e.ename,e.esal,d.dno,d.dname,sg.grade from empolee left out join dept on (e.dno=d.dno)
left out join salgrade on(e.sal between sg.lowsal and sg.hihsal);

四、自连接查询

自连接用于同一张表的连接查询处理。实质上每查询一次都会产生一章临时表。

1、解决方案

​ 把一张表看作多张表。本表——》临时表——》本表。

2、案例

查询员工的编号、姓名和上级的编号以及姓名;

SELECT t.`empno` '员工编号',t.`ename` '姓名',e.`mrg_id` '上级编号',e.`ename` '上级姓名' FROM empolee AS t LEFT OUTER JOIN empolee e ON (t.mrg_id = e.dno);

猜你喜欢

转载自blog.csdn.net/qq_45095925/article/details/127219462