参考:https://blog.csdn.net/lj1994104/article/details/79671807
A)内连接:join,inner join
B)外连接:left join,left outer join,right join,right outer join,union
C)交叉连接:cross join
创建两张表,把表当成一个集合那么表中的元素就是集合的一个元素
创建a表
CREATE TABLE `a` ( `id` int(10) NOT NULL AUTO_INCREMENT, `age` int(2) DEFAULT NULL, PRIMARY KEY (`id`) ) ;
创建b表
CREATE TABLE `b` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ;
插入测试数据
mysql> select * from a inner join b on a.id=b.id; +----+------+----+-------+ | id | age | id | name | +----+------+----+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | +----+------+----+-------+
应用场景
这种场景下得到的是满足某一条件的A,B内部的数据;本次需要满足的条件是a.id等于b。id
正因为得到的是内部共有数据,所以连接方式称为内连接。
mysql> select * from a left join b on a.id=b.id; +----+------+------+-------+ | id | age | id | name | +----+------+------+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | | 1 | 10 | NULL | NULL | +----+------+------+-------+
Table B中不存在的记录填充NULL
应用场景
mysql> select * from a left join b on a.id=b.id where b.id is null; +----+------+------+------+ | id | age | id | name | +----+------+------+------+ | 1 | 10 | NULL | NULL | +----+------+------+------+
应用场景
这种场景下得到的是A中的所有数据减去"与B满足同一条件 的数据",然后得到的A剩余数据;
mysql> select * from a right join b on a.id=b.id; +------+------+----+-------+ | id | age | id | name | +------+------+----+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | | NULL | NULL | 5 | chen | +------+------+----+-------+
应用场景
这种场景下得到的是B的所有数据,和满足某一条件的A的数据;
mysql> select * from a right join b on a.id=b.id where a.id is null; +------+------+----+------+ | id | age | id | name | +------+------+----+------+ | NULL | NULL | 5 | chen | +------+------+----+------+
应用场景
这种场景下得到的是B中的所有数据减去 "与A满足同一条件 的数据“,然后得到的B剩余数据;
mysql> select * from a left join b on a.id=b.id union select * from a right join b on a.id=b.id; +------+------+------+-------+ | id | age | id | name | +------+------+------+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | | 1 | 10 | NULL | NULL | | NULL | NULL | 5 | chen | +------+------+------+-------+
union过后,重复的记录会合并(id为2,3,4的三条记录),
应用场景
这种场景下得到的是满足某一条件的公共记录,和独有的记录
mysql> select * from a left join b on a.id=b.id where b.id is null union select * from a right join b on a.id=b.id where a.id is null; +------+------+------+------+ | id | age | id | name | +------+------+------+------+ | 1 | 10 | NULL | NULL | | NULL | NULL | 5 | chen | +------+------+------+------+
应用场景
这种场景下得到的是A,B中不满足某一条件的记录之和
2.3.1 实际应用中还有这样一种情形,想得到A,B记录的排列组合,即笛卡儿积,这个就不好用集合和元素来表示了。需要用到cross join:
mysql> select * from a cross join b; +----+------+----+-------+ | id | age | id | name | +----+------+----+-------+ | 1 | 10 | 2 | zhang | | 2 | 11 | 2 | zhang | | 3 | 12 | 2 | zhang | | 4 | 13 | 2 | zhang | | 1 | 10 | 3 | li | | 2 | 11 | 3 | li | | 3 | 12 | 3 | li | | 4 | 13 | 3 | li | | 1 | 10 | 4 | zhou | | 2 | 11 | 4 | zhou | | 3 | 12 | 4 | zhou | | 4 | 13 | 4 | zhou | | 1 | 10 | 5 | chen | | 2 | 11 | 5 | chen | | 3 | 12 | 5 | chen | | 4 | 13 | 5 | chen | +----+------+----+-------+
2.3.2 还可以为cross join指定条件 (where):
mysql> select * from a cross join b where a.id=b.id; +----+------+----+-------+ | id | age | id | name | +----+------+----+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | +----+------+----+-------+
注:这种情况实际上实现了内连接
上面仍然存在遗漏,那就是mysql对sql语句的容错问题,即在sql语句不完全符合书写建议的情况,mysql会允许这种情况,尽可能地解释它:
3.1 一般cross join后面加上where条件,但是用cross join+on也是被解释为cross join+where;
3.2 一般内连接都需要加上on限定条件,如上面场景2.1;如果不加会被解释为交叉连接;
3.3 如果连接表格使用的是逗号,会被解释为交叉连接;
注:sql标准中还有union join和natural inner join,mysql不支持,而且本身也没有多大意义,其结果可以用上面的几种连接方式得到
原文:https://www.cnblogs.com/minseo/p/14333399.html