SQL表联接

所有的连接一般分为两大类:

内部联接

外部链接

一.内部联接

内部联接的两个语法

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标准语法

猜你喜欢

转载自shijiaqi1066.iteye.com/blog/1580983