我有一个问题是理解一个非常简单但有趣的查询,涉及2个右外连接和'非顺序'on-expression . 这是查询:
select * from C
right outer join A on A.F1 = C.F1
right outer join B on B.F1 = C.F1;
以下是表格:
create table A ( F1 varchar(200));
create table B ( F1 varchar(200));
create table C ( F1 varchar(200));
这是一些行:
insert into A values ('A');
insert into A values ('B');
insert into A values ('C');
insert into B values ('B');
insert into B values ('C');
insert into B values ('D');
insert into C values ('A');
insert into C values ('C');
insert into C values ('D');
注意:查询 select * from C right outer join A on A.F1 = C.F1 right outer join B on B.F1 = C.F1; join表达式都引用表C.
查询返回(在列中然后是行)
(NULL,NULL, B),(C, C, C).(NULL, **NULL**, D)
我期待(我对SQL的了解不多)
(NULL,NULL, B),(C, C, C),(NULL, **D**, D)
SQL(在Microsoft SQL和MySQL上测试)获得这些值的逻辑顺序是什么 .
在我的“执行”序列中,我坐在表A的A值,null(对于B),C,null(对于D)和表B中,在“产品”之前为空(对于A),B,C,D与C(B,C,D)合并 .
Gawie PS:我使用MySQL以及Microsoft SQL 2008对此进行了测试......结果相同 .
4 回答
表A不包含字段'D',因此D不可能出现在结果集Gawie的第二列中 . 结果集中的字段将是C.F1,A.F1,B.F1(与表在连接中出现的顺序相同) .
C,A - >(A,A),(NULL,B),(C,C)
然后右连接B(匹配第一列,因为连接在B.F1 = C.F1上):
C,A,B - >(NULL,NULL,B),(C,C,C),(NULL,NULL,D)
这是我迷路的地方......
为什么C,A,B不等于(NULL,B,B),等等
对于C,A对于B列等于(NULL,B)右外连接(NULL,B)与B应该产生(NULL,B,B)...除非匹配被反转! C,A,B - >(NULL,B,B)(这显然是错误的 - 只是不完全理解为什么)
表“A”中没有要加入的D值,这就是它返回NULL而不是您期望的D的原因 . 当您通过列别名确定值来自哪个表时,更容易看到:
右连接按它们出现的顺序(从左到右)进行评估 . 让我们从
from C
开始:然后
right join A
,加入A.F1 = C.F1
:然后
right join B
(匹配第一列,因为连接在B.F1 = C.F1
上):因为
from C right join A
在第一列中不包含D,所以right join B
无法匹配,并为C和A的列追加一个包含NULL的行,为B中的列追加D
.