日期:2013-05-08  浏览次数:20679 次

  • 链接:

作为动词,它表示将两个或多个表的内容结合在一同并产生一个结果集,该结果集对每个表的列和行进行合并。表的联接普通都使用它们共有的数据。例如,您可以对有一个共同 pub_id 列的 titles 表和 publishers 表联接,产生一个包含书名信息和出版商信息的结果集。

作为名词,表示对表进行联接的过程或结果,如在术语"内部联接"中表示对表联接的一种特殊的方法。

  • 联接条件(join condition)

一个比较子句,它指定了表是如何通过它们的联接字段相联系的。最普通的联接条件是相等(一个等联接),在等联接中联接字段的值必须相反。例如,您可以通过在 titles 表和 publishers 表的 pub_id 列中查找相婚配的值联接这两个表。然而,任何比较运算符都可以是比较条件的一部分。

  • 内部联接(inner join)

一个联接,在该联接中只要当联接字段的值满足某些特定的准绳时才将两个表的记录进行结合并添加到一个查询结果中。例如,在查询设计器视图中,表之间的缺省联接是一个内部联接,它只要当联接字段的值相等时才从两个表中选择记录。

  • 外部联接(outer join)

一个联接,该联接还包括那些和联接表中记录不相关的记录。您可以创建一个外部联接的三种变形来指定所包括的不婚配行:左外部联接、右外部联接和完全外部联接。

  • 左外部联接(left outer join)

一种外部联接类型,在该联接中包括第一个命名表(左边的表,它出如今 JOIN 子句的最左边)的所有行。左边表中没有婚配的行不出现。例如,您可以在 titles 表和 publishers 表之间创建一个左外部联接,以包括所有的书名,不论书名有无出版商的信息。

  • 右外部联接(right outer join)

一种外部联接,在该联接中包括第二个命名表(左边的表,出如今 JOIN 子句中的最左边)的所有行。不包括左边表中没有婚配的行。例如,titles 表和 publishers 表之间的一个右外部联接将包括所有的出版商,甚至包括那些在 titles 表中没有书名的出版商。

以上是MSDN中对链接的定义。如今我们就从这四种链接所使用的不同方法来看他们的结果有什么不同。

titles 表sh(书号)  ph(出版商编号)232342  0010432  00382478123 005

publishers 表
ph(出版商编号) mc(出版商名称)
001 红虎
002 rmh
003 hazl

现要把这两个表的内容合成如下的表结构:

sh(书号)    ph(出版商编号)        mc(出版商名称)

如今看看采用四种链接方法的结果会有什么不同。先说说他们的命令:

内联接:
sele titles.sh,publishers.ph,publishers.mc ;
  from titles inner join publishers ;    &&内联接中的inner是可以省略的
    on titles.ph=publishers.ph

外联接:
sele titles.sh,publishers.ph,publishers.mc ;
  from titles outer join publishers ;
    on titles.ph=publishers.ph

左联接:
sele titles.sh,publishers.ph,publishers.mc ;
  from titles left join publishers ;
    on titles.ph=publishers.ph

右联接:
sele titles.sh,publishers.ph,publishers.mc ;
  from titles right join publishers ;
    on titles.ph=publishers.ph

大家可能看到,除了在join之前的那个关键字不同之外,其他地方是如出一辙的,链接条件(即on那一部分)也是一样的。结果:

内链接:

232342  001 红虎0432  003 hazl

全链接:

232342  001 001 红虎Null  Null 002 rmh0432  003 003 hazl82478123 005 Null Null

左链接:

232342  001 001 红虎0432  003 003 hazl82478123 005 Null Null

右链接:

232342  001 001 红虎Null  Null 002 rmh0432  003 003 hazl

所以我们很容易记住:

1、左链接:就是以join的左边那个表为"主",以titles.ph=publishers.ph为判断标准,不管左边的表有没有对应的记录,都要把左边表的记录放在结果中去,但左边表没有相应的记录那应该放个什么数值进去?答案是就放个Null,表示没有。在左链接中,某记录在左边表,却不在左边表,那是不放进去结果去的,缘由是左边表才是"主",要不要放由它决定:它有的,就一定放进去,它没有的,就不要了。

2、右链接:和左链接一样,只不过为"主"的一方调过来了,换成是由左边做"主"。

3、内链接:和左、右链接不同,它一定要左、右两边都有的记录才会放进结果,如果有某个记录不存在于任何一边,那这个记录是不会出如今结果中去的。

4、外链接:跟内联接相,反,相当于左、右链接的合并:不管什么情况,只需某个记录出如今这两个表,就一定会出如今结果中去,然后象左、右链接的处理方法一样,用Null来填充没有对应值的字段。

注:以上说的"有"、"没有",意思是以titles.ph=publishers.ph为判断标准来下决定的。比如当前titles表的ph是"002",而在publishers中,没有一个记录的ph的值是"002"的,所以就说"002"这个值在titles有,在publisher中没有,这样titles.ph为"002"的记录就会被选中,最后放在结果中去。

大家如果想一下,这个on的作用跟where、having似乎有点类似,都是起到过滤的作用:依据条件选取所取的记录,而依据命令的任务流程,这个on是比where、having都要早执行的,而它里面的条件表达式又不一定是titles.ph=publishers.ph的方式,还可以继续扩充,变成一个很复杂的条件表达式,从而完成一个很无效的、where和having都不能实现的过滤功用。具体的比较请看 on、where、having的区别 一节。

刚才举的例子,表中的ph都是没有反复的。如今以内联接为例,举个判断字段中内容有反复的例子:

Temp1  temp2Aa  aa1  11  22  23  2
sele temp1.aa,temp2.aa ;  from temp1 join temp2 ;    on temp1.aa=temp2.aa

运转结果是:

1 11 12 22 22 2

很明显,有些记录反复了几遍。temp1.aa中的虽然只要1个2,但temp2.aa有3个2,所以结果就会有1*3=3个2了。如果temp1.aa而2个2的话,那结果就会有2*3=6个2了。

知道了这一点,在做多表链接查询的时候很有用。你要考虑第一、二个链接后的结果跟第三个表链接时,会不会出现这种情况?如果有,那是不是你想要的?如果有,那怎样处理?有些朋友说做这个命令的结果中有些记录会比正确的结果大几倍,就要看看是不是出现了这种反复算的情况。

学会了链接,在开始做之前,先要说一个很重要的问题:在视图设计器来看多个表的联接关系,它们之间的链接是用一条线连接起来的,看起来就象一串糖葫芦。如果一个表同时和三个表联接,那看起来就象一支分叉的树枝了,那这种情况结果就不对了。大家可能不明白我在说什么,我举个例子大家就会明白了。

有一个产品表、一个进货明细表、一个出货明细表,如今的要求是要求产品表中所有的产品的进、出情况,也就是把三个表象join命令那样合成一个表,如果没有相应的进、出记录,也照样列出来但不计较null值。刚开始学的朋友很可就会这样做:

1、 在设计器里添加这三个