MySQL外连接
参见MySQL内连接:http://my.oschina.net/xinxingegeya/blog/385220
外连接并不要求连接的两表的每一条记录在对方表中都一条匹配的记录. 连接表保留所有记录——甚至这条记录没有匹配的记录也要保留。
外连接可依据连接表保留左表,右表或全部表的行而进一步分为左外连接, 右外连接和全连接。
(在这种情况下left<左> 和 right<右> 表示 JOIN 关键字的两边.)
在标准的 SQL 语言中, 外连接没有隐式的连接符号。
左外连接(left outer join),亦简称为左连接(left join),若 A 和 B 两表进行左外连接,那么结果表中将包含"左表"(即表 A)的所有记录, 即使那些记录在"右表" B 没有符合连接条件的匹配。这意味着即使 ON 语句在 B 中的匹配项是0条,连接操作还是会返回一条记录,只不过这条记录中来自于 B 的每一列的值都为 NULL。这意味着左外连接会返回左表的所有记录和右表中匹配记录的组合(如果右表中无匹配记录, 来自于右表的所有列的值设为 NULL)。如果左表的一行在右表中存在多个匹配行。那么左表的行会复制和右表匹配行一样的数量, 并进行组合生成连接结果。
如下示例,
select * from course c left join student_course sc on c.cid = sc.cid;
这是嵌套循环关联的结果,如何用伪代码来解释这个结果集呢?如下伪代码,请见:http://my.oschina.net/xinxingegeya/blog/342402#OSC_h1_2
mysql> select tb1.col1,tb2.col2 -> from tb1 left outer join tb2 using col3 -> where tb1.col1 in (5,6);
outer_iter = iterator over tb1 where col1 in (5,6) outer_row = outer_iter.next while outer_row inner_iter = iterator over tb2 where col3 = outer_row.col3 inner_row = inner_iter.next if inner_row while inner_row output [outer_row.col1, inner_row.col2] inner_row = inner_iter.next end else output [outer_row.col1,NULL] end outer_row = outer_row.next end
在左连接中,当右表即B表没有匹配的行时,执行else操作,打印出左表和NULL,即output [outer_row.col1,NULL]
右外连接,亦简称右连接,它与左外连接完全类似,只不过是作连接的表的顺序相反而已。如果 A 表右连接 B 表, 那么"右表" B 中的每一行在连接表中至少会出现一次。如果 B 表的记录在"左表" A中未找到匹配行,连接表中来源于 A 的列的值设为 NULL。
右连接操作返回右表的所有行和这些行在左表中匹配的行(没有匹配的, 来源于左表的列值设为 NULL)。
如下示例,
select * from course c right join student_course sc on c.cid = sc.cid;
实际上显式的右连接很少使用,因为它总是可以被替换成左连接--换换表的位置就可以了,另外,右连接相对于左连接并没有什么额外的功能。
如下把上面的换成左连接,
select * from student_course sc left join course c on c.cid = sc.cid;
都会得到如下的结果集,
全连接是左右外连接的并集。连接表包含被连接的表的所有记录,如果缺少匹配的记录,即以 NULL 填充。
MySQL不支持全连接。
一些数据库系统(如 MySQL)并不直接支持全连接,但它们可以通过左右外连接的并集(参: union)来模拟实现。
select * from course c left join student_course sc on c.cid = sc.cid union select * from course c right join student_course sc on c.cid = sc.cid where c.cid is not null;
======================================END======================================