sql - Oracle 语法左连接三个或更多表

标签 sql oracle join left-join

我正在努力思考旧的 oracle Left Join 语法。 有两个表就可以了:

FROM A, B
WHERE
A.Col = B.Col (+)

(让我们调用这个查询,Q0)

这很容易理解,例如用这个维恩 diagram

但是,当我们添加第三张或更多张 table 时,我的大脑就会停止运转:

FROM A,B,C
WHERE 
A.C = B.C (+) AND
C.C = A.C (+)

(我们称之为 Q1)

应该等于:(我刚刚更改了左侧连接条件的位置)

FROM A,B,C
WHERE 
C.C = A.C (+) AND
A.C = B.C (+)

(我们称之为 Q2)

下面是我对这些问题的看法,我的问题是我是否理解正确:

根据我的理解,解释 2 个以上表的左连接的一种方法是将其视为左连接链,其中一个是另一个的输入,这是否正确?

所以在 Q1 中我们有两个左连接,第一个是 A Left Joined with B,其中 A 是左表。第二个左连接对我来说开始变得棘手。起初我以为是表 C 与表 A 左连接,其中 C 是左表。但这似乎是不正确的,而应该看作是 C 左连接与第一个左连接的结果,其中 C 是左表。 这是正确的吗?

但是我如何在 Q2 中应用这个“链原则”?

我尝试复制 Q1 中的推理:第一个连接是 C 左连接与 A,其中 C 是左表。第二个连接是 A 和第一个连接的结果之间的左连接,其中 A 是左表。但这没有意义,第二次左连接的连接条件是在A列和B列之间,而第一次左连接的结果中没有B列。

出于好奇+我尝试在第二个连接中切换左右表,这是第一个连接的结果将在第二个左连接中充当左表,与 B 左连接。这似乎有效,结果与 Q1 相同。但我不知道如何解释为什么会这样。

因此,如果有人可以建议一种在使用 oracle 语法时一般适用于三个或更多表的推理方法,我们将不胜感激。 如果这样的通用方法包含将 oracle 语法转换为 ANSI 语法的通用方法,它也会这样做,因为我可以更容易地理解它。

最佳答案

可以层叠的方式看。但是,关键是要查找在同一查询中左右连接的那些表。在这种情况下,顺序不同:首先应用表右连接的条件。我希望下图能对此有所启发:

enter image description here

您还可以通过查看查询的执行计划来检查这些连接的顺序:

对于第一季度:

select a.c a, b.c b, c.c c   from a, b, c  where a.c = b.c (+)    and
c.c = a.c (+)

------------------------------------------------------------------------
| Id  | Operation           | Name | E-Rows |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |        |       |       |          |
|*  1 |  HASH JOIN OUTER    |      |      4 |  2168K|  2168K|  805K (0)|
|*  2 |   HASH JOIN OUTER   |      |      4 |  2616K|  2616K|  981K (0)|
|   3 |    TABLE ACCESS FULL| C    |      4 |       |       |          |
|   4 |    TABLE ACCESS FULL| A    |      4 |       |       |          |
|   5 |   TABLE ACCESS FULL | B    |      4 |       |       |          |
------------------------------------------------------------------------

对于第二季度:

select a.c a, b.c b, c.c c   from a, b, c  where c.c = a.c (+)    and
a.c = b.c (+)

------------------------------------------------------------------------
| Id  | Operation           | Name | E-Rows |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |        |       |       |          |
|*  1 |  HASH JOIN OUTER    |      |      4 |  2168K|  2168K|  801K (0)|
|*  2 |   HASH JOIN OUTER   |      |      4 |  2616K|  2616K|  983K (0)|
|   3 |    TABLE ACCESS FULL| C    |      4 |       |       |          |
|   4 |    TABLE ACCESS FULL| A    |      4 |       |       |          |
|   5 |   TABLE ACCESS FULL | B    |      4 |       |       |          |
------------------------------------------------------------------------

关于sql - Oracle 语法左连接三个或更多表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24236637/

相关文章:

MySQL:在不满足关系的情况下显示A.id和B.id

MySQL连接查询4张表

mysql - 如何将行值放入新列中以提高可读性?

c# - 数据库连接(最佳实践)

oracle - SQLDeveloper 使用超过 100MB 的 PGA

oracle - 以静默模式安装 Oracle 数据库时如何忽略可选先决条件?

sql - 在 Oracle SQL Developer 中执行存储过程

mysql - 如何在 mySql 中使用 Join 添加三行并保留在第三列行

sql - 如何找到当前时间段与任何表字段匹配?

sql - 在 Redshift 中使用 DISTINCT 的 listagg