内连接 外连接 交叉连接

声明一下:博文内容中的SQL语句都使用 MySQL 5.6.25 版本通过测试,博文内容侧重于对SQL理论的理解,对于不同的数据库实现或是SQL版本,可能会存在一些差异!

数据库表连接大致分为三种:交叉连接、内连接、外连接

交叉连接(CROSS JOIN):其实就是内连接的一种特例,不带查询条件

内连接(INNER JOIN):相等连接、不等连接、自然连接

外连接(OUTER JOIN):左外联接、右外链接、全外连接(全外连接只有部分RDBMS系统可以做到,例如 Oracle 、SQL Server。做不到的例如 MySQL、Access)

交叉连接

最简单,返回多张表每一行相乘的结果,也就是笛卡尔积。关键字是 CROSS JOIN。交叉连接从定义上讲,应该是不带连接条件的,但是实际上有些数据库(例如 MySQL)允许在 CROSS JOIN 后面加上连接条件,这个时候就和内联接的效果一样了。

1 SELECT * FROM tb_person CROSS JOIN tb_book;

内连接

相等连接:就是条件使用等值符号(=)

不等连接:就是条件使用不等符号(>,>=,<,<=,!>,!<,<>)

自然连接:只有在两张表中含有相同的列名称时,才能使用自然连接,自然连接默认利用同名列构造出相等连接,实际用处并不大。

1 SELECT * FROM tb_person INNER JOIN tb_book ON tb_person.id = tb_book.person_id;  -- 相等连接
2 SELECT * FROM tb_person INNER JOIN tb_book ON tb_person.id <> tb_book.person_id;  -- 不等连接
3 SELECT * FROM tb_person NATURAL JOIN tb_book;  -- 自然连接

JOIN 到底是不是 INNER JOIN 的简写形式?

1 SELECT * FROM tb_person JOIN tb_book;

查阅《SQL权威指南》第四版,发现:JOIN 是SQL-92标准加入的一种新语法,是SQL的表连接操作,在SQL语句中如果使用 JOIN 操作符,但是又没有指定 JOIN 类型,那么就隐式使用 INNER 类型。

我的理解是 JOIN 本身就是SQL语法的一部分,可以独立存在,并不依附于谁,说 JOIN 是 INNER JOIN 的简写,似乎有些缩小范围。说 JOIN 默认使用 INNER 类型可能会更好一些。当然每个人的理解的角度可能不一样,说它是简写也好,不是简写也好,都没有太大关系,重要的是理解它,会使用。

外连接

注重两张表之间的关系,也就是表的左右顺序,通常称之为左表和右表。

左外连接(LEFT OUTER JOIN):接收左表中的每一行,并利用这些行与右表匹配,找出右表中符合条件的行,最终连接形成数据结果集。如果对于左表行记录右表找不到能与之匹配的行记录,就会使用NULL替代右表,得到连接匹配结果。当左表与右表具有一对多关系时,左外联接特别有用。

右外连接(RIGHT OUTER JOIN):与左外联接是相同的道理,只是右表占主导地位而已。如果把左外联接中的左表和右表互换位置,得到的就是右外连接的结果。

全外连接(FULL OUTER JOIN):综合了左外连接和右外连接的特性,左表和右表地位相同,左表无匹配数据用NULL替代,右表无匹配数据也用NULL替代,也就是说左表和右表的数据都会在查询结果里面,不会少数据。

1 SELECT * FROM tb_person LEFT OUTER JOIN tb_book ON tb_person.id = tb_book.person_id;
2 SELECT * FROM tb_person LEFT JOIN tb_book ON tb_person.id = tb_book.person_id;  -- 简写
3 
4 SELECT * FROM tb_person RIGHT OUTER JOIN tb_book ON tb_person.id = tb_book.person_id;
5 SELECT * FROM tb_person RIGHT JOIN tb_book ON tb_person.id = tb_book.person_id;  -- 简写
6 
7 -- 外联接不是每一种数据库都有的特性
8 SELECT * FROM tb_person FULL OUTER JOIN tb_book ON tb_person.id = tb_book.person_id;
9 SELECT * FROM tb_person FULL JOIN tb_book ON tb_person.id = tb_book.person_id;  -- 简写

ON 和 WHERE 的区别

可能有些朋友发现了这样一个问题,下面两句 SQL 得到的结果是一样的

1 SELECT * FROM tb_person INNER JOIN tb_book ON tb_person.id = tb_book.person_id;
2 SELECT * FROM tb_person INNER JOIN tb_book WHERE tb_person.id = tb_book.person_id;

以前我没有深入理解 ON 和 WHERE 的区别,经过2#提点,查询资料及实际测试后,我发现在某些情况下,它们可能会得到相同的结果,但是理论上它们是不一样的,就好比“条条道路通罗马”,最终的目的虽然是一样的,但是每条路是不一样的。

首先明确一点,SQL在连接表的时候,大部分情况下,都会产生一张中间表,用于返回数据结果。

ON 用于表与表之间的连接操作,是连接条件,在SQL执行连接,产生中间表的时候用到,此时还没有得到最终的数据结果。

WHERE 是SQL得到最终中间表,也就是的数据结果后,对数据进行筛选的时候用到,是筛选条件。

正确的使用 ON 和 WHERE ,可以优化SQL,提高SQL的执行效率。

原文地址:https://www.cnblogs.com/litmmp/p/4890698.html