假设我有一个这样的表:
主表:
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
中选择一列,因此它应该在结果集中
这不起作用。当j
和m
在同一个FROM
子句中时,这种外部联接语法(显然(起作用。
无论如何,子查询正在实现外部联接。我的简单猜测是,语法的设计者没有实现考虑子查询的功能,因为子查询已经是一个外部联接。在这一点上,关于(+)
的文档至少已有20年的历史,因此很难弄清楚这样的意图。
20年前,Oracle取代了(+)
语法。我的建议是不要使用它。它不是外部联接的推荐语法。子查询不需要它。
您从Main表中选择元素,然后从联接表中选择第二个表中的id与主表中项目的id匹配的元素。由于id为1的第二个表中没有元素,因此其他表中没有匹配项,因此结果为null。