Oracle“(+)”运算符


155

我正在检查一些旧的SQL语句,以记录它们并可能对其进行增强。

DBMS是Oracle

我不明白这样的声明:

select ...
from a,b
where a.id=b.id(+)

我对(+)运算符感到困惑,并且无法在任何论坛上找到它((在引号内搜索+也不起作用)。

无论如何,我使用了SQLDeveloper的“解释计划”,并且得到了这样的输出HASH JOIN, RIGHT OUTER,等等。

如果(+)在查询末尾删除运算符,会有什么区别?在使用数据库之前,是否必须满足一些条件(例如具有一些索引等)(+)?如果您可以为我提供一个简单的理解,或者可以从中获得一些好的链接,这将对您有所帮助。

谢谢!


1
它不是运算符。这只是影响JOIN所做的一部分语法。
philipxy

Answers:


186

这是OUTER JOIN的Oracle特定表示法,因为ANSI-89格式(在FROM子句中使用逗号分隔表引用)没有使OUTER联接标准化。

该查询将以ANSI-92语法重新编写为:

   SELECT ...
     FROM a
LEFT JOIN b ON b.id = a.id

该链接很好地解释了JOIN之间的区别


还应该注意的是,即使可行(+)Oracle建议不要使用它

Oracle建议您使用FROM子句OUTER JOIN语法而不是Oracle join运算符。使用Oracle连接运算符的外部连接查询(+)受以下规则和限制的约束,这些规则和限制不适用于FROM子句OUTER JOIN语法:


79
非常正确。为了使(+)直立在我的头部(左侧和右侧),我想将(+)视为“如果找不到匹配项,则添加NULL值”。例如,“ a.id = b.id(+)”表示如果与a.id不匹配,则允许b.id为NULL。
海滩

谢谢..我想在from子句中添加它应该产生相同的结果!
Kiran S

您可能需要在Oracle官方文档中找到
Vargan 2015年

27

(+)运算符表示外部联接。这意味着即使没有匹配项,Oracle仍将从联接的另一端返回记录。例如,如果a和b是emp和dept,并且您可以将雇员取消分配到部门,则以下语句将返回所有雇员的详细信息,无论是否已将他们分配到部门。

select * from emp, dept where emp.dept_id=dept.dept_id(+)

简而言之,删除(+)可能会产生显着差异,但您可能会暂时不注意,具体取决于您的数据!


25

在Oracle中,(+)表示JOIN中的“可选”表。因此,在您的查询中,

SELECT a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id(+)

这是表'b'到表'a'的左外部联接。当另一端(可选表'b')没有数据时,它将返回表'a'的所有数据而不会丢失其数据。

左外连接图

相同查询的现代标准语法为

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b ON a.id=b.id

或简称a.id=b.id(并非所有数据库都支持):

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
LEFT JOIN b USING(id)

如果删除(+),则将是普通的内部联接查询

在Oracle和其他数据库中,较旧的语法:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id=b.id

更现代的语法:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
INNER JOIN b ON a.id=b.id

或者简单地:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
JOIN b ON a.id=b.id

内部联接图

它只会返回“ a”和“ b”表的“ id”值相同的所有数据,表示公共部分。

如果您想使查询成为右联接

这与LEFT JOIN相同,但是切换哪个表是可选的。

右外连接图

旧的Oracle语法:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a,b
WHERE a.id(+)=b.id

现代标准语法:

SELECT  a.id, b.id, a.col_2, b.col_2, ...
FROM a
RIGHT JOIN b ON a.id=b.id

参考与帮助:

https://asktom.oracle.com/pls/asktom/f?p=100:11::::::P11_QUESTION_ID:6585774577187

在Oracle 11g中使用+登录进行左外部联接

https://www.w3schools.com/sql/sql_join_left.asp


圆形标签“ table1”和“ table2”是废话。圆形元素的最简单含义是输出行。然后,左新月包含table1的空扩展行,右新月包含table2的空扩展行。圆圈的其他含义不明确。您认为这些图表到底意味着什么?除了盲目复制别人的(不好的)演示文稿之外,您为什么还要把它们放在其他地方?
philipxy

您现在已将圆圈标记为a和b。圆圈不是a和b的行。左右圆圈可以合理地标记为左连接b和右连接b的行。此外,您不会根据输入描述那些圈起来的行。自己弄清楚圈子里发生了什么。如果要在圆圈上粘贴标签a和b,请用文字清楚地说明每个标签与圆圈的关系。(没有直接的理由将它们标记为a和b。)最好正确标记绿色区域。
philipxy

6

实际上,+符号直接放在条件语句中和可选表的一侧(允许在条件表中包含空值或null值的表)。


(+)紧接在列名的右侧。这个答案还不清楚。“实践中”应该指的是什么?(修辞。)(您可能不是
要说
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.