SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
ANSI standard SQL specifies four types of JOIN
:
RIGHT
As a special case, a table (base table, view, or joined table) can JOIN
to itself in a self-join.
1.1内连接有两种形式:显示内连接形式和隐式内连接形式。
显示是使用关键字 inner join 关键字。
e.g. select * from tableA INNER JOIN tableB ON tableA.id = tableB.id
隐式就是在from后面跟上表名,即一般的多表查询
e.g. select * from tableA, tableB where tableA.id = tableB.id
An outer join does not require each record in the two joined tables to have a matching record. The joined table retains each record—even if no other matching record exists. Outer joins subdivide further into left outer joins, right outer joins, and full outer joins, depending on which table(s) one retains the rows from (left, right, or both).
(In this case left and right refer to the two sides of the JOIN
keyword.)
No implicit join-notation for outer joins exists in standard SQL.
外连接表的分类
在探究外连接示例之前,重要的是首先要了解连接中是如何分类表的。
外连接的 FROM 子句中的表可以被分类成保留行(preserved row)表或者替换 NULL(NULL-supplying)的表。保留行表是指那些在连接操作中没有匹配的内容时,把行保留下来的表。因此,将返回保留行表中所有满足 WHERE 子句要求的行,无论在连接中是否存在匹配的行。
保留行表是:
当不存在匹配的行时,替换 NULL 的表替换 NULL。如果连接操作中不存在匹配,任何在 SELECT 列表或者随后的 WHERE 或者 ON 子句中引用的替换 NULL 的表中的列都将包含 NULL。
替换 NULL 的表是:
在全外连接中,两张表既可以保留行,也可以替换 NULL。 这一点非常重要,因为有些规则适用于纯粹的保留行表,但是如果该表也替换 NULL,则会变得不适用。
在 FROM 子句中编写表的顺序对于左外连接、右外连接以及涉及两张表以上的连接极端重要,因为当连接中存在不匹配的行时,保留行表和替换 NULL 的表的表现不同。
2.1 LEFT OUTER Join
左外连接返回那些存在于左表而右表中却没有的行,加上内连接的行。那些来自保留行表的未匹配行会被保留,而那些来自替换 NULL 的表中的行会以 NULL 替换。
2.2 RIGHT OUTER Join
右外连接返回那些存在于右表而左表中没有的行( DEPTNO = 'A00'
),加上内连接的行。那些来自保留行表的未匹配行会被保留,而那些来自替换 NULL 的表中的行会由 NULL 替换。对于右外连接,右表会成为保留行表,而左表会成为替换 NULL 的表。
2.3 FULL OUTER Join
全外连接返回那些存在于右表但不存在于左表的行,加上那些存在于左表但不存在于右表的行,还有内连接的行。
这两张表既替换 NULL,也保留行。然而,因为存在分别适用于替换 NULL 的表和保留行表的“查询改写”和“WHERE 子句谓词求值”的规则,所以表被标识为替换 NULL 的表。我会在随后的示例中更多地描述这之间的差异。
e.g. select * from tableA A LEFT OUTER JOIN tableB B ON A.id = B.id
where A.id > 3;
会先得到连接后的结果再应用where的条件过滤得到最的结果。
e.g. select * from tableA A LEFT OUTER JOIN tableB b ON A.id = B.id AND A.id = 3;
是用A表左连接B表,只对A中id=3的行,连接B中的行,对于结果,A中id <> 3的,B中的列会是NULL。
参考:
Wiki: Join(SQL)
http://en.wikipedia.org/wiki/Join_(SQL)
Terry Purcell 谈外连接
http://www.ibm.com/developerworks/cn/data/library/techarticles/0112purcell/0112purcell.html
http://www.ibm.com/developerworks/cn/data/library/techarticles/0201purcell/0201purcell.html
图解SQL的Join
http://coolshell.cn/articles/3463.html