您的位置:首页 > 其它

连接表

2011-07-06 22:17 92 查看
连接表一个连接表是根据特定的连接规则从两个其它表(真实表或生成表)中派生的表。我们支持内连接、外连接、交叉连接。

连接类型

交叉连接
T1CROSSJOINT2
对每个来自T1和T2的行进行组合,生成的表将包含这样的行:所有T1里面的字段后面跟着所有T2里面的字段。如果两表分别有N和M行,连接成的表将有N*M行。

FROMT1CROSSJOINT2等效于FROMT1,T2。它还等效于FROMT1INNERJOINT2ONTRUE(见下文)。

条件连接
T1{[INNER]|{LEFT|RIGHT|FULL}[OUTER]}JOINT2ONboolean_expression
T1{[INNER]|{LEFT|RIGHT|FULL}[OUTER]}JOINT2USING(joincolumnlist)
T1NATURAL{[INNER]|{LEFT|RIGHT|FULL}[OUTER]}JOINT2
INNER和OUTER对所有连接类型都是可选的。INNER为缺省。LEFT,RIGHT,FULL隐含外连接。

连接条件在ON或USING子句里声明,或者用关键字NATURAL隐含地声明。连接条件判断来自两个源表中的那些行是"匹配"的,这些我们将在下面详细解释。

ON子句是最常见的连接条件的类型:它接收一个和WHERE子句相同的布尔表达式。如果两个分别来自T1和T2的行在ON表达式上运算的结果为真,那么它们就算是匹配的行。

USING是个一个连接条件的缩写语法:它接收一个用逗号分隔的字段名列表,这些字段必须是连接表共有的并且其值必须相同。最后,JOINUSING会将每一对相等的输入字段输出为一个字段,其后跟着所有其它字段。因此,USING(a,b,c)等效于ON(t1.a=t2.aANDt1.b=t2.bANDt1.c=t2.c)只不过是如果使用了ON,那么在结果里a,b,c字段都会有两个,而用USING的时候就只会有一个。

最后,NATURAL是USING的缩写形式:它自动形成一个由两个表中同名的字段组成的USING列表(同名字段只出现一次)。

条件连接可能的类型是:

INNERJOIN内连接。对于T1中的每一行R1,如果能在T2中找到一个或多个满足连接条件的行,那么这些满足条件的每一行都在连接表中生成一行。

LEFTOUTERJOIN左外连接。首先执行一次内连接。然后为每一个T1中无法在T2中找到匹配的行生成一行,该行中对应T2的列用NULL补齐。因此,生成的连接表里无条件地包含来自T1里的每一行至少一个副本。

RIGHTOUTERJOIN右外连接。首先执行一次内连接。然后为每一个T2中无法在T1中找到匹配的行生成一行,该行中对应T1的列用NULL补齐。因此,生成的连接表里无条件地包含来自T2里的每一行至少一个副本。

FULLOUTERJOIN全连接。首先执行一次内连接。然后为每一个T1与T2中找不到匹配的行生成一行,该行中无法匹配的列用NULL补齐。因此,生成的连接表里无条件地包含T1和T2里的每一行至少一个副本。

如果T1和T2之一或全部是可以连接的表,那么所有类型的连接都可以串连或嵌套在一起。你可以在JOIN子句周围使用圆括弧来控制连接顺序,如果没有圆括弧,那么JOIN子句从左向右嵌套。

为了解释这些问题,假设我们有一个表t1

num|name
-----+------
1|a
2|b
3|c
和t2

num|value
-----+-------
1|xxx
3|yyy
5|zzz
然后我们用不同的连接方式可以获得各种结果:

=>SELECT*FROMt1CROSSJOINt2;
num|name|num|value
-----+------+-----+-------
1|a|1|xxx
1|a|3|yyy
1|a|5|zzz
2|b|1|xxx
2|b|3|yyy
2|b|5|zzz
3|c|1|xxx
3|c|3|yyy
3|c|5|zzz
(9rows)

=>SELECT*FROMt1INNERJOINt2ONt1.num=t2.num;
num|name|num|value
-----+------+-----+-------
1|a|1|xxx
3|c|3|yyy
(2rows)

=>SELECT*FROMt1INNERJOINt2USING(num);
num|name|value
-----+------+-------
1|a|xxx
3|c|yyy
(2rows)

=>SELECT*FROMt1NATURALINNERJOINt2;
num|name|value
-----+------+-------
1|a|xxx
3|c|yyy
(2rows)

=>SELECT*FROMt1LEFTJOINt2ONt1.num=t2.num;
num|name|num|value
-----+------+-----+-------
1|a|1|xxx
2|b||
3|c|3|yyy
(3rows)

=>SELECT*FROMt1LEFTJOINt2USING(num);
num|name|value
-----+------+-------
1|a|xxx
2|b|
3|c|yyy
(3rows)

=>SELECT*FROMt1RIGHTJOINt2ONt1.num=t2.num;
num|name|num|value
-----+------+-----+-------
1|a|1|xxx
3|c|3|yyy
||5|zzz
(3rows)

=>SELECT*FROMt1FULLJOINt2ONt1.num=t2.num;
num|name|num|value
-----+------+-----+-------
1|a|1|xxx
2|b||
3|c|3|yyy
||5|zzz
(4rows)
用ON声明的连接条件也可以包含与连接不直接相关的条件。这种功能可能对某些查询很有用,但是需要我们仔细想清楚。比如:

=>SELECT*FROMt1LEFTJOINt2ONt1.num=t2.numANDt2.value='xxx';
num|name|num|value
-----+------+-----+-------
1|a|1|xxx
2|b||
3|c||
(3rows)
摘自《PostgreSQL8.2.3中文文档》7.2.1.1节。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: