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

时间:2014-06-16 04:24:14

标签: sql oracle join left-join

我试图围绕旧的oracle Left Join语法。 两张桌子没关系:

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

(让我们称之为查询,Q0)

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

但是当我们在我的大脑想要关闭的时候添加第三张或更多的桌子时:

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语法的一般方法,那也会这样做,因为我可以更容易理解。

2 个答案:

答案 0 :(得分:3)

你可以以层叠的方式看到它。但是,关键是要查找在同一查询中左右连接的表。在这种情况下,顺序是不同的:首先应用表正确连接的条件。我希望下面的图表能说明这一点:

enter image description here

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

对于Q1:

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 |       |       |          |
------------------------------------------------------------------------

答案 1 :(得分:1)

与标准ANSI OUTER JOINS(以及可读性恕我直言)相比,

(+)样式外连接在功能方面较差,Oracle自9i以来一直支持。

你想要的是什么

FROM C
LEFT JOIN A ON C.C = A.C
LEFT JOIN B ON A.C = B.C

现在有意义吗?说实话,我不太明白你的问题,因为上面的语法对我来说真的很明显......