MySQL中的连接查询
一共有7大连接查询,如下图所示

通过举例来理解吧。
建库建表
1 | USE test; |
1 | SELECT * FROM t_emp; # 10 |

一共有10条记录。
1 | SELECT * FROM t_dept; # 6 |

部门有6条记录,表示六大门派
七大连接查询
AB共同
即查询两张表中共同的部分,即上图的交集。

查询所有 有门派的人员信息:
1 | SELECT * FROM t_emp a INNER JOIN t_dept b ON a.`deptId` = b.`id`; |

从结果中发现,门派表中的“少林”与员工表的“韦小宝”不在查询结果中。只查询了两表的交集部分。因为韦小宝不属于任何门派,而员工表中没有少林派的人员。
A的全集

列出所有用户,并显示其机构信息:
1 | SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.`deptId` = b.`id`; |

要求列出所有的用户,应该使用左连接, 员工表为主表,将主表 中的数据全部查询出来,从表是部门表,与员工表不对应的部分查询为NULL。
B的全集

列出所有门派 :
1 | SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.`deptId` = b.`id`; |

上述结果中,将所有的门派查询出来了,右边的表为主表,而左边的员工表中,有匹配的就查询,无匹配的就填充NULL。
A的独有
所谓A的独占就是说查询出来的结果中只在A表中出现的记录,B表中无匹配。

相当于A的全集中将中间的“抠掉”, 也就是说将两表的公共部分去掉。其标准查询模板是:
1 | Select <select list> from A left join B on a.key = b.key where b.key IS NULL; |

如: 查询所有不入门派的人员, 我们需要做的就是将上面红框部分的去掉,获取剩下的蓝色框部分。
1 | SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.`deptId` = b.`id` WHERE b.`id` IS NULL; |

B的独有

同上的分析。相当于B的全集中将中间的“抠掉”, 也就是说将两表的公共部分去掉,或者说我要去的B的独有部分,A 就没啥事情了,将B全集中结果去掉A的那部分就是B的独有了。其标准查询模板是:
1 | Select <select list> from A right join B on a.key = b.key where a.key IS NULL; |
查询所有没人入的门派:

1 | SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.`deptId` = b.`id` WHERE a.`deptId` IS NULL; |

查出来的是少林派,的确是少林派没有人加入。
AB全有

其标准查询模板是:
1 | select <select list > from A FULL OUTER JOIN B ON A.key = B.key; |
列出所有人员和门派的对应关系:
1 | SELECT * FROM t_emp a FULL OUTER JOIN t_dept b ON a.`deptId` = b.`id`; |
保存如下:

这是因为MYSQL不支持FULL JOIN
。
可以使用UNION, 可以去重
1 | SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.`deptId` = b.`id` |

分析一下, 一目了然,就是三个的并集:

A的独有+B的独有

列出所有没入派的人员和没人入的门派
没入派的就是韦小宝,没人入的门派是少林派
和上面一样,就是A的独有并上B的独有,也可以使用UNION关键字
1 | # 7. 列出所有没入派的人员和没人入的门派 |

进阶
如果在上面的部门表上加上对应的门派掌门字段
1 | ALTER TABLE t_dept ADD CEO INT(11); |

求各个门派对应的掌门人名称:
1
SELECT * FROM t_dept b LEFT JOIN t_emp a ON a.`id`= b.`CEO`;
求所有当上掌门人的平均年龄:
1
SELECT AVG(a.`age`) FROM t_emp a INNER JOIN t_dept b ON a.`id` = b.`CEO`;
求所有人物对应的掌门名称:
1
2
3SELECT c.`name` NAME, ab.name ceoName FROM t_emp c LEFT JOIN
(SELECT b.`id`, a.`name` FROM t_dept b LEFT JOIN t_emp a ON a.`id`= b.`CEO`) ab
ON c.`deptId`= ab.id;这里涉及到了三表连接。在第一题中我们已经查询到了每一个门派的掌门姓名,然后我们需要查询每一个人对应的掌门姓名,可以利用第一题查询 到的结果作为另一张表,然后使用员工表去左连接查询。