所有的连接一般分为两大类:
内部联接
外部链接
一.内部联接
内部联接的两个语法
SQL:2003
定义的语法使用SELECT语句的FROM子句来连接表:
…
from <table>
[inner|natural|cross] join <table>
[on <condition>]|[using <column name>,…],…
…
说明:
1.内部联接选项
在一个内部联接中,有下列选项:
INNER关键字是可选的,它用于明确区分内部联接和外部链接。
NATURAL关键字用于指定两个表之间的自然连接,即通过名称相同的列将两个表联接起来。NATURAL关键字不能同时调用ON和USING字句。在三大RDBMS中,只有Oracle 11g可以使用NATURAL。
CROSS 关键字用于交叉联接。
2.ON和USING字句
ON子句指定连接条件(等值连接或非等值连接)。
指定一个自然连接时,USING子句指示要使用的列。当自然联接无法正常工作时,也将用到USING子句。
在三大RDBMS中,只有Oracle 11g支持USING字句,但ON字句也可以得到相同的结果。
旧语法
每个供应商通常都使用另一个语法在WHERE子句执行连接。
...
where
[<qualifier>.]<coluimn_name><join_condition> [<qualifier>.]<coluimn_name>
and
[<qualifier>.]<coluimn_name><join_condition> [<qualifier>.]<coluimn_name>
, ...
在等同联接中,join_condition可以是=
在非等同联接中,join_condition可以是>,<,>=,<=,!=
等同联接
最常用的表连接类型,两列之间完全匹配。
SQL:2003标准语法
select cust_id_n,cust_name_s,phone_phonenum_s,phone_type_s
from customer join phone
on cust_id_n=phone_custid_fn
自然联接
自然联接是一种在RDBMS中执行的同等联接特例,基于下面的假设:“总是通过名称相同的一列(或多列)联接表。”
换言之,在SELECT语句的FROM子句中,不需要在ON分子句中显示指定列,完全省略分子句ON。
旧语法
在SELECT语句的WHERE子句中联接表。
该语法的反对者的主要观点是WHERE子句中不能混合联接和谓词,它的唯一目的是对产生的结果集设置“
垂直”限制。
支持者的主要观点是对于联接很多表的查询,旧语法更具有可读性。另一个主要争论点是遗留代码,尤其
是对于Oracle,在9i版本之前,标准语法都是不好用的。
非同等联接
有时需要基于条件而不是等同性来联接表。同等联接的典型应用时处理主键/外键关系,而非同等联接则不同,非同等联接通常会以一种无意义的方式填充结果集。
例:如果用<>(不等于)代替前一节查询中的=(等于)运算符,那么查询结果将返回所有客户和电话号码的组合。而不豪阔那些实际上标识有效客户、电话号码的列表。换言之,结果和笛卡尔积有些相似。
自连接
自连接:一个表不与其他表而与自身进行连接。
尽管实际上表与自身进行连接,但是处理的仍然是同一表的两个实例。或者说是两个相同的表,而不只是一个表,所以,自联接可以认为是多表联接的一种特殊情况。
注意:理解一个表和它实例的不同之处也是很重要的。两个表实例可以认为是表的数据被载入两个不同的存储单元,彼此完全分离。
SELECT r.reseller_id_n AS res_id,
r.reseller_name_s AS res_name,
s.reseller_id_n AS sup_id,
s.reseller_name_s AS sup_name
FROM reseller r JOIN reseller s
on r.reseller_supplier_id=s.reseller_id_n
交叉连接(笛卡尔积)
两个表的交叉联接或笛卡尔积,可以定义为从两个源表中,选取可能的匹配行组成另一个表(可能是虚表)。
SQL:2003
select cust_name_s,phone_phonenum_s from customer cross join phone
旧语法
select cust_name_s,phone_phonenum_s from customer , phone
对两个以上的表进行连接
多表联接的联接数目
n个表的查询中,应该至少有n-1个连接。如果少于n-1个联接,结果将是一个笛卡尔积。
注意:最常见的(和最危险的)交叉联接类型发生在包含两个以上的表的查询中,这种情况下,不必省略where子句,只需要跳过十几个表中的两个表的联接就足够了。
SQL2003
连接4个表的查询中
select distinct customer.cust_name_s
from customer
join order_head
on customer.cust_id_n=order_header.ordhdr_custid_fn
join order_line
on order_head.ordhdr _id_n= order_line. ordline_ordhdrid _fn
join product
on product.prod_id_n=order_line. ordline_prodid_fn
旧语法
在where子句中写入联接条件。
二.外部联接
根据包含NULL值的列联接表
外部联接的两个语法
SQL:2003
…
from <table>
{left|right|full[outer]}|union join
<table>
[on <condition>]|[using <column name>,…]
, …
但是只有Oracle实现了using字句。
旧语法
使用where子句。但Oracle和SQL Server实现方式也不相同(DB2没有用于外部联接的“旧”语法,它一开始旧兼容SQL2003)
Oracle 11g
旧的右外联接或左外联接,通过在表面之后添加一个(+)来表示,并且这个表在=的相应边没有匹配行,完
全外部联接只能通过与SQL:2003兼容的语法指定。
右外连接
...
where
[<qualifier>.]<coluimn_name>= [<qualifier>.]<coluimn_name>(+)
...
左外连接
...
where
[<qualifier>.]<coluimn_name>(+)= [<qualifier>.]<coluimn_name>
...
左外部联接
外部连接背后的总体思想是检索表A(左)或表B(右)的所有行,如果在对应的表中没有匹配值,联接列便为NULL。一个左(或右)外部联接对所有连接表中不匹配的列也返回NULL值(只包含那些含NULL联接列的行时)。
1.SQL2003标准语法