首页 > 解决方案 > 子查询中的外连接不返回值

问题描述

假设我有一张这样的桌子:

主表:

id | value
-----------
1  | 'not null'

联表:

id | value
-----------
2  | 'id does not match, whatever'

和这样的选择语句:

SELECT
  m.value without_join,
  (SELECT
     m.value with_join
   FROM
     joined_table j
   WHERE
     j.id(+) = m.id) joined
FROM
  main_table m;

返回结果如下:

without_join | with_join
-------------------------
not null     | (null)

即使我加入了(+)运算符,也执行了内部联接而不是外部联接。由于在子查询中没有选择行,m.value因此返回的是空值。

我期望的行为是在子查询中外部加入jm因此从m表中返回非空值。

标签: sqloraclesubqueryouter-join

解决方案


我假设你明白为什么这会返回NULL

SELECT m.value as without_join,
       (SELECT m.value with_join
        FROM joined_table j
        WHERE j.id = m.id
       ) as joined
FROM main_table m;

内连接没有匹配。

我能理解你的逻辑。它是这样的:

  • 子查询正在执行外部联接(尽管没有明确的join语法)。
  • 它应该保留所有的值m,填写不匹配的j遗嘱NULL值。
  • 子查询返回一行。
  • 子查询正在从 中选择一列m,因此它应该在结果集中。

这行不通。这种外连接语法(显然)在同一子句j中时有效。mFROM

无论如何,子查询都在实现外连接。我的简单猜测是语法的设计者没有实现子查询的考虑功能,因为子查询已经是一个外连接。在这一点上,文档(+)至少有 20 年的历史,因此很难弄清楚这样的意图。

(+)二十年前,Oracle 取代了该语法。我的建议就是不要使用它。这不是外连接的推荐语法。子查询不需要它。


推荐阅读