1

我在理解一个非常简单但有趣的查询时遇到了问题,该查询涉及带有“非顺序”表达式的 2 个右外连接。这是查询:

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; 连接表达式都引用表 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 中,null(对于 A)、B、C、D 在“产品”之前与 C (B,C,D) 合并。

Gawie PS:我使用 MySQL 和 Microsoft SQL 2008 对此进行了测试……结果相同。

4

4 回答 4

1

表“A”中没有要加入的 D 值,这就是它返回 NULL 而不是您期望的 D 的原因。当您通过列别名识别值来自哪个表时,更容易看到:

SELECT c.f1 AS c, a.f1 AS a, b.f1 AS b 
  FROM c 
RIGHT JOIN A on A.F1 = C.F1 
RIGHT JOIN B on B.F1 = C.F1
于 2010-07-14T21:47:10.807 回答
0

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,B列的A等于(NULL,B)与B的右外连接(NULL,B)应该产生(NULL,B,B)......除非匹配被反转!C, A, B --> (NULL, B, B) (这显然是错误的——只是不完全理解为什么)

于 2010-07-15T09:54:44.467 回答
0

表 A 不包含字段“D”,因此 D 不可能出现在结果集 Gawie 的第二列中。结果集中的字段将为 C.F1、A.F1、B.F1(与表在连接中出现的顺序相同)。

于 2010-07-14T21:46:43.847 回答
0

右连接按照它们出现的顺序进行评估(从左到右)。让我们从from C

C        -->  (A), (C), (D)

然后right join A,加入A.F1 = C.F1

C, A     -->  (A, A), (NULL, B), (C, C)

然后right join B(匹配第一列,因为连接是 on B.F1 = C.F1):

C, A, B  -->  (NULL, NULL, B), (C, C, C), (NULL, NULL, D)

因此,因为from C right join A在第一列中不包含 D,所以right join B无法匹配,并为来自 C 和 AD的列以及来自 B 的列附加包含 NULL 的行。

于 2010-07-14T21:46:44.757 回答