添加 2-table 条件时,Oracle 左外连接停止返回结果

Oracle left outer join stops returning results when 2-table condition added

我有一个 oracle sql 查询,其中包含一整串内连接和左连接。但是,当我添加最后一个左连接条件时,它会停止返回结果。这可能最终是一个像 "you can't outer join on columns from 2 tables" 这样的简单答案,但我找不到适用于 oracle 的任何此类规则,并且有大量示例显示相反的情况。 sql 查询是:

  FROM a, b,
       c, d,
       e, f,
       g, h,
       (SELECT id5 FROM
        some_table WHERE
           conditions) i,
       (SELECT id7, type FROM
        some_other_table WHERE
           conditions) j
  WHERE b.time in (range) AND
        b.count <> 0 AND
        b.id1 = e.id1 AND
        e.type = g.type AND
        g.type2 = f.type2 AND
        b.id2 = a.id2(+) AND
        b.time = a.time(+) AND
        b.id3 = c.id3(+) AND
        b.time = c.time(+) AND
        c.id4 = d.id4(+) AND
        c.time = d.time(+) AND
        c.id5 = i.id5(+) AND
        c.time = h.time(+) AND
        c.id6 = h.id6(+) AND
        h.id7 = j.id7(+); --AND
        --e.type = j.type(+);

当我取消注释最终条件时,没有返回任何结果。由于这应该是外部联接,因此不应该发生这种情况。所以,这里一定有什么东西让它不像外部连接?

这里有错别字或错误吗?我违反了 oracle 规则吗?有什么可以通过切换到 ANSI 连接格式来解决的吗?

谢谢

要么是您在将查询转换为简单形式时遗漏了某些内容,要么是我在处理过程中遗漏了一些内容,但看起来查询可能没有按照您的预期进行。以标准 ANSI 形式重写更能说明问题:

FROM a
right outer join b
  on  b.id2  = a.id2
  AND b.time = a.time
right outer join c
  on  c.id3  = b.id3
  AND c.time = b.time
left outer join d
  on  d.id4  = c.id4
  AND d.time = c.time
join e
  on  e.id1 = b.id1
cross join f
join g
  on  g.type  = e.type
  AND g.type2 = f.type2
left outer join h
  on  h.time = c.time
  AND h.id6  = c.id6
left outer join(
     SELECT id5 FROM
      some_table WHERE
         conditions) i
  on  i.id5 = c.id5
left outer join(
     SELECT id7, type FROM
      some_other_table WHERE
         conditions) j
  on  j.id7 = h.id7
  and j.type = e.type   --> the criteria in question
where b.time in (range)
  AND b.count <> 0;

这对你来说合适吗?你没有提到 RIGHT OUTER 加入,但我希望你只是忘记了。您确实提到了 INNER 联接,但是 table f 根本没有联接条件,所以我使用了 CROSS 联接,希望这也是您的意图。

tablee 的加入标准是否应该如此?根据您设置的模式,我希望在这里看到 "id5" 而不是 "id1"。当然,你已经更改了所有名称以提交一个简化的示例,因此这可能毫无意义。因此,我首先建议您像我一样,使用真实的 table 和列名将原始代码重写为 ANSI 格式。你可能会看到一些东西。

您是正确的,添加标记的条件应该不会影响结果集中的行数。既然如此,那就有事了。

要找出什么,请注释掉整个最后一个连接。如果您发现有问题,请继续注释掉 tables 以找到问题发生的地方。如果一切正常,则只执行构成 "table" j 的嵌套查询。我想不出它可能包含的任何内容会导致您解释的情况,但无论如何都要检查一下。

最后,如果所有其他方法都失败了,请仅使用 tables e 和 j 形成查询,然后仅使用 tables h 和 j(及其相应的连接条件)。看看会发生什么。

然后回到这里向我们解释为什么问题一直出在其他地方。 :)

问题(正如问题评论中所建议的)是 h.id7 = j.id7(+) AND e.type = j.type(+) 在功能上等同于 a.id1 = b.id1(+) and c.id2 = b.id2(+)。 oracle join语法不够精确,看不出,由于其他join条件,这不是full outer join,所以不允许。

这应该会导致错误,但查询中的其他内容抑制了错误,我不清楚这是怎么发生的。无论如何,切换到 ANSI 格式使我能够更精确地指定连接条件,并且查询按预期工作。