图解MySQL连接(最详细,看完包会!), join 大合集
作者:互联网
;当一张表的数据无法满足我们的需求时,就需要进行多表查询,而多表查询分为多种情况,这里我先用图来展示,后面用代码验证。
内连接
inner join 内连接,取的就是两张表的交集。
select 字段 from tableA inner join tableB on A.key = B.key
左(外)连接
left join 左(外)连接,那就是要左表的全部,A和B的共有加上A的独有。
select 字段 from tableA left join tableB on A.key = B.key。
如果A中有的B没有,那么就会用null来补齐。
右(外)连接
right join 右(外)连接,右,那就是要右表的全部,A和B的共有加上B的独有。
select 字段 from tableA right join tableB on A.key = B.key
如果B中有而A中没有,那么就会用 null 来补齐。
全(外)连接
full outer join,全外连接,就是查询两张表的独有加共有。
select 条件 from tableA full outer join tableB on A.key = B.key MySQL不支持
MySQL如何实现,请看后面代码分析。
扩展
下面再说几种情况。
查询A独有
经过上面分析,可以知道,左连接是AB共有加A独有,B没有则用null补齐。那么如果我现在就想要得到A的独有呢?也就是实现下图:
其实也很简单,因为A独有,那么就是B没有,只需要加上一条 where B.key IS NULL 即可,也就是select 字段 from tableA left join tableB on A.key = B.key where B.key IS NULL。
经过where设置B.key IS NULL,即可过滤掉公共部分,剩下A独有部分。
查询B独有
实现下图效果:
如法炮制,既然是查询B独有,那就是A没有,在右连接时加上一条 where B.key IS NULL 即可,也就是
select 条件 from tableA right join tableB on A.key = B.key where A.key IS NULL 。
经过where设置A.key IS NULL,即可过滤掉公共部分,剩下B独有部分。
查询各自独有
实现下图效果:
也就是去掉公共部分,中间镂空,只查询A的独有和B的独有,那么也很简单。SQL如下:
select 条件 from tableA full outer join on A.key = B.key where A.key IS NULL and B.key IS NULL
MySQL不支持full outer join,但是思想不变,后面代码分析如何实现。
JOIN 代码编写
创建员工表和部门表,并给上一些测试数据。
测试用表和数据奉上:
CREATE TABLE `tbl_emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`deptId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) ,
KEY `fk_dept_id`(`deptId`)
)ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8;
CREATE TABLE `tbl_dept` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`deptName` varchar(30) DEFAULT NULL,
`locAdd` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8;
insert into tbl_dept(deptName,locAdd) values('RD',11);
insert into tbl_dept(deptName,locAdd) values('HR',12);
insert into tbl_dept(deptName,locAdd) values('MK',13);
insert into tbl_dept(deptName,locAdd) values('MIS',14);
insert into tbl_dept(deptName,locAdd) values('FD',15);
insert into tbl_emp(NAME,deptId) values('z3',1);
insert into tbl_emp(NAME,deptId) values('z4',1);
insert into tbl_emp(NAME,deptId) values('z5',1);
insert into tbl_emp(NAME,deptId) values('w5',2);
insert into tbl_emp(NAME,deptId) values('w6',2);
insert into tbl_emp(NAME,deptId) values('s7',3);
insert into tbl_emp(NAME,deptId) values('s8',4);
insert into tbl_emp(NAME,deptId) values('s9',51);
为了方便观看,我也将表结构截图展示出来。
tbl_emp表
由雇员的id、雇员的name、雇员的部门id组成。
这里留意一下 deptId,有一个 51,这个 deptId是 tbl_dept 表中没有的。
tbl_dept表
由部门的id、部门名称、部门位置组成,这里部门位置没啥用,就是凑个字段…
这里留意下 id,有一个是 5 ,这是 tbl_emp 表中没有的。
笛卡尔积现象
先试下两个表连接,不给连接条件,会出现什么问题。
可以看到,因为我没有给连接条件,所以tbl_emp中的每一条记录都会去匹配tbl_dept中的记录,所以就会有 5 * 8 ,也就40条记录。
内连接展示
sql中 e 和 d是我给两个表起的别名。
可以看到,A(tbl_emp)表和B(tbl_dept)表的共有部分被查询出来。而他们各自独有的记录并没有查询出来。
左(外)连接展示
可以看到,A(tbl_emp)表和B(tbl_dept)表的共有部分被查询出来,并且A的独有部分也被查询出来。这就是左(外)连接。
右(外)连接展示
可以看到,A(tbl_emp)表和B(tbl_dept)表的共有部分被查询出来,并且B的独有部分也被查询出来。这就是右(外)连接。
查询A独有展示
使用左连接查询,然后使用where过滤,得到A的独有。
查询B独有展示
使用→连接查询,然后使用where过滤,得到B的独有。
全连接展示
由于MySQL不支持 full outer join,所以全连接需要使用到一个关键字,叫做 union。union的效果就是合并且去重。
全外连接就是查询A、B表的共有,加上A表的独有和B表的独有。这里先用 左连接 和 右连接 先查出A、B共有和A表独有以及A、B共有和B表独有,但是这样公共部分重复了,此时 union 就登场了,union天生带有去重性质,将两次查询结果的重复部分去掉,就得到了全外连接的结果。
查询各自独有展示
使用左连接和右连接并用where过滤掉公共部分得到各自独有部分,然后再通过union进行合并就可以,这里并没有去重的过程。
总结
这几种连接都是学习以及工作中会用到的最基本的,也是最核心的,必须要牢牢掌握,然后向更高进发。
标签:join,MySQL,独有,tbl,key,包会,查询,连接,emp 来源: https://blog.csdn.net/weixin_44061521/article/details/120802608