Loading

JOIN(连接)众生相

JOIN语句的其实是用来合并数据,或着说是进行集合运算的语句,而合并数据的理论是以关系代数(Relation Algebra) 为基础的。关系代数是一种抽象的查询语言,用对关系的运算来表达查询,用作研究关系数据语言的数学工具。

在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。连接的全部意义在于在水平方向上合并两个数据集合(通常是表),并产生一个新的结果集合,其方法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。
SQL提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。

SQL中有五种连接(JOIN),分别是:左连接(Left Join)、右连接(Right Join)、等值连接(Inner Join)、全外连接(Full Outer Join)、交叉连接(Cross Join)。

左连接(LEFT JOIN)

左连接(Left Join),其全名应该是左外连接(Left Outer Join),包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行。

左连接的语法:

select column_name(s)
  from table_name1
  left join table_name2
    on table_name1.column_name = table_name2.column_name

Examples over LEFT JOIN

Persons:

id lastname firstname address city
1 Adams John Oxford Street London
2 Bush George Fifth Avenue New York
3 Carter Thomas Changan Street Beijing

Orders:

id order_no person_id
1 77895 3
2 44678 3
3 22456 1
4 33489 1
5 78945 65

现在,我们希望列出所有的人,以及他们的定购 - 如果有的话,可以使用下面的 SELECT 语句:

select persons.lastname,
       persons.firstname,
       orders.order_no
  from persons
  left join orders
    on persons.id=orders.person_id
 order by persons.lastname

执行上面的SQL语句,我们会得到如下结果集:

lastname firstname order_no
Adams John 22456
Adams John 33489
Carter Thomas 44678
Carter Thomas 77895
Bush George  

LEFT JOIN 关键字会从左表 (Persons) 那里返回所有的行,即使在右表 (Orders) 中没有匹配的行。

右连接(RIGHT JOIN)

右连接(Right Join),其全名应该是左外连接(Right Outer Join),包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行。

右连接的语法:

select column_name(s)
  from table_name1
 right join table_name2
    on table_name1.column_name = table_name2.column_name

Examples over RIGHT JOIN

还是使用上面的Persons和Orders表,如果我们希望列出所有的订单,以及下单的人(如果有的话),可以使用下面的 SELECT 语句:

select persons.lastname,
       persons.firstname,
       orders.order_no
  from persons
 right join orders
    on persons.id=orders.person_id
 order by orders.order_no

这们会得到如下的结果集:

order_no lastname firstname
22456 Adams John
33489 Adams John
44678 Carter Thomas
77895 Carter Thomas
78945    

LEFT JOIN 关键字会从右表 (Orders) 那里返回所有的行,即使在左表 (Persons) 中没有匹配的行。

内连接(INNER JOIN)

内连接(Inner Join),是用比较运算符比较要连接列的值的连接,只连接匹配的行。

内连接的语法:

select column_name(s)
  from table_name1
 inner join table_name2
    on table_name1.column_name = table_name2.column_name

Examples Over INNER JOIN

我们继续使用上面的两个表,现在,我们希望列出所有的人,以及他们的定购,可以使用下面的 SELECT 语句:

select persons.lastname,
       persons.firstname,
       orders.order_no
  from persons
 inner join orders
    on persons.id=orders.person_id
 order by persons.lastname

我们会得到下面的结果集:

lastname firstname order_no
Adams John 22456
Adams John 33489
Carter Thomas 44678
Carter Thomas 77895

INNER JOIN关键字只会返回左右表都匹配的行。

全外连接(FULL OUTER JOIN)

全外连接(Full Outer Join)返回参与连接的两个数据集合中的全部数据,无论它们是否具有与之相匹配的行。在功能上,它等价于对这两个数据集合分别进行左外连接和右外连接,然后再使用消去重复行的并操作将上述两个结果集合并为一个结果集。
在现实生活中,参照完整性约束可以减少对于全外连接的使用,一般情况下左外连接就足够了。在数据库中没有利用清晰、规范的约束来防范错误数据情况下,全外连接就变得非常有用了,你可以使用它来清理数据库中的数据。

全外连接的语法:

select column_name(s)
  from table_name1
  full outer join table_name2
    on table_name1.column_name = table_name2.column_name

Examples Over FULL OUTER JOIN

如果我们要对上面的Persons表和Orders表进行全外连接合并,可以使用下面的语句:

select persons.lastname,
       persons.firstname,
       orders.order_no
  from persons
  full outer join orders
    on persons.id=orders.person_id

我们会得到如下的结果集:

lastname firstname order_no
Adams John 22456
Adams John 33489
Carter Thomas 44678
Carter Thomas 77895
Bush George  
    78945

你会发现,全外连接首先列出了匹配的行,然后对于不匹配的行也列了出来,虽然这些行可以没有任何意义。

交叉连接(CROSS JOIN)

交叉连接用于对两个源表进行纯关系代数的乘运算。它不使用连接条件来限制结果集合,而是将分别来自两个数据源中的行以所有可能的方式进行组合。数据集合中一的每个行都要与数据集合二中的每一个行分别组成一个新的行。例如,如果第一个数据源中有5 个行,而第二个数据源中有4个行,那么在它们之间进行交叉连接就会产生20个行。人们将这种类型的结果集称为笛卡尔乘积。
大多数交叉连接都是由于错误操作而造成的,但是它们却非常适合向数据库中填充例子数据,或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。

交叉连接的语法:

select column_name(s)
  from table_name1
 cross join table_name2

在交叉连接中没有on条件子句和Where语句的。

如果对前面的Persons表和Orders表进行交叉连接运算:

select persons.lastname,
       persons.firstname,
       orders.order_no
  from persons
 cross outer join orders

我们会得到3*5=15条记录:

lastname firstname order_no
Adams John 22456
Adams John 33489
Adams John 44678
Adams John 77895
Adams John 78945
Carter Thomas 22456
Carter Thomas 33489
Carter Thomas 44678
Carter Thomas 77895
Carter Thomas 78945
Bush George 22456
Bush George 33489
Bush George 44678
Bush George 77895
Bush George 78945
posted @ 2012-11-09 13:14  光脚码农  阅读(496)  评论(0编辑  收藏  举报