子查询中的外部联接不返回值



假设我有一个这样的表:

主表:

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

我期望的行为是在子查询中将j外部联接到m,因此从m表返回非空值。

我想您已经理解为什么会返回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中选择一列,因此它应该在结果集中

这不起作用。当jm在同一个FROM子句中时,这种外部联接语法(显然(起作用。

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

20年前,Oracle取代了(+)语法。我的建议是不要使用它。它不是外部联接的推荐语法。子查询不需要它。

您从Main表中选择元素,然后从联接表中选择第二个表中的id与主表中项目的id匹配的元素。由于id为1的第二个表中没有元素,因此其他表中没有匹配项,因此结果为null。

最新更新