2 SQL语句中的右外连接
我在理解一个非常简单但有趣的查询时遇到问题,该查询涉及带有“非顺序”表达式的 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 右外联接 A on A.F1 = C.F1 右外联接 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)。
加维 PS:我已经使用 MySQL 以及 Microsoft SQL 2008 对此进行了测试......结果相同。
I have an issue in understanding a very simple yet interesting query concerning 2 right outer joins with 'non-sequential' on-expressions. Here is the query:
select * from C
right outer join A on A.F1 = C.F1
right outer join B on B.F1 = C.F1;
Here are the tables:
create table A ( F1 varchar(200));
create table B ( F1 varchar(200));
create table C ( F1 varchar(200));
Here are some rows:
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');
Note: The query select * from C right outer join A on A.F1 = C.F1 right outer join B on B.F1 = C.F1; join expressions both refers to table C.
The query returns (in columns then rows)
(NULL,NULL, B),(C, C, C).(NULL, **NULL**, D)
and I expected (in my little understanding of SQL)
(NULL,NULL, B),(C, C, C),(NULL, **D**, D)
What is the logical sequence whereby SQL (tested on Microsoft SQL as well as MySQL) get to these values.
In my "execution" sequence I sit with on table A values of A, null (for B), C, null (for D) and in Table B, null (for A), B, C, D before the "product" is amalgamated with C (B,C,D).
Gawie
PS: I have test this using MySQL as well as Microsoft SQL 2008... with the same results.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
表“A”中没有要连接的 D 值,这就是它返回 NULL 而不是您期望的 D 的原因。当您通过列别名识别值来自哪个表时,更容易看到:
There's no D value in table "A" to join to, which is why it returns NULL instead of the D you expect. It's easier to see when you identify which table the value is coming from via column alias:
表 A 不包含字段“D”,因此 D 不可能出现在结果集 Gawie 的第二列中。结果集中的字段将为 C.F1、A.F1、B.F1(与表在联接中出现的顺序相同)。
Table A doesn't contain a field 'D', so there's no way that D can appear in the second column in the result set, Gawie. The fields in the result set will be C.F1, A.F1, B.F1 (in the same order that the tables appear in the joins).
右连接按照它们出现的顺序(从左到右)进行计算。让我们从
from C
开始:然后
right join A
,连接A。 F1 = C.F1
:然后
右连接 B
(匹配第一列,因为连接位于B.F1 = C.F1
):所以因为
来自 C 的右联接 A
第一列中不包含 D,右联接 B
无法匹配,并为来自 C 和 A 的列追加包含 NULL 的行,以及 B 中的列的D
。Right joins are evaluated in the order in which they appear (from left to right.) Let's start with
from C
:Then
right join A
, joining onA.F1 = C.F1
:Then
right join B
(matching the first column, since the join is onB.F1 = C.F1
):So because
from C right join A
does not contain an D in the first column, theright join B
fails to match, and appends a row containing NULL for the column from C and A, andD
for the column from B.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)
与 B 的右外连接 (NULL, B) 应该产生 (NULL, B, B)...除非匹配相反!
C、A、B——> (NULL, B, B) (这显然是错误的 - 只是不完全理解为什么)
C, A --> (A, A), (NULL, B), (C, C)
Then right join B (matching the first column, since the join is on B.F1 = C.F1):
C, A, B --> (NULL, NULL, B), (C, C, C), (NULL, NULL, D)
This is where I get lost...
Why is C, A, B not equal to (NULL, B, B), ... etc
for C, A for column B equals (NULL, B)
right outer join (NULL, B) with B should yield (NULL, B, B)... unless the matching is reversed!
C, A, B --> (NULL, B, B) (which is obviously wrong - just don't completely understand why)