【问题标题】:Outer join in subquery does not return value子查询中的外连接不返回值
【发布时间】:2019-04-08 18:27:39
【问题描述】:

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

主表:

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 表中返回非空值。

【问题讨论】:

  • 好的,你知道为什么SELECT * FROM main_table m返回一行而SELECT * FROM main_table m JOIN joined_table j ON m.id = j.id不返回任何行吗?
  • 拉迪姆,我愿意。但是,以下语句:SELECT * FROM main_table m LEFT OUTER JOIN joined_table j ON m.id = j.id 返回一些行。我不明白为什么在子选择中执行内连接而不是外连接。
  • 这似乎是一个有效的(虽然非常过时)的问题。我不明白反对票。
  • 为什么有什么不同,为什么它们应该相同? PS minimal reproducible example PS 甚至 Oracle 都说,不要使用 (+),使用 left join。尽管您没有将(+), 一起使用,但它没有任何效果。阅读有关左连接的手册。 PS请通过帖子编辑澄清,而不是cmets。

标签: sql oracle subquery outer-join


【解决方案1】:

我假设你明白为什么这会返回 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的所有值,填写jNULL值不匹配。
  • 子查询返回一行。
  • 子查询正在从m 中选择一列,因此它应该在结果集中。

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

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

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

【讨论】:

  • “子查询正在实现外连接”和“子查询已经是外连接”应该是什么意思?
  • @philipxy 。 . .相关子查询将外部表中的所有行与内部表中的匹配值一起保留。这等效于外连接(尽管每次匹配限制为一行)。该语法不使用JOIN,但在功能上等价于外连接。
【解决方案2】:

您正在从主表中选择元素,然后从第二个表中的 id 与主表中项目的 id 匹配的连接表中选择元素。由于第二个表中没有id为1的元素,所以另一个表中没有匹配,所以结果为null。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2013-08-17
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多