在我们正在迁移(通用)的基于Oracle的应用程序中找到以下内容:
SELECT
Table1.Category1,
Table1.Category2,
count(*) as Total,
count(Tab2.Stat) AS Stat
FROM Table1, Table2
WHERE (Table1.PrimaryKey = Table2.ForeignKey(+))
GROUP BY Table1.Category1, Table1.Category2
(+)
在WHERE子句中做了什么?我以前从未见过这样的用法。
答案 0 :(得分:88)
根据“=”的哪一侧“(+)打开,它表示LEFT OUTER或RIGHT OUTER join(在这种情况下,它是左外连接)。它是旧的Oracle语法,有时是首选由首先学习它的人,因为他们喜欢它,使他们的代码更短。
为了便于阅读,最好不要使用它。
答案 1 :(得分:23)
正如其他人所说,(+)
语法是过时的专有语法,Oracle多年来使用该语法来完成与OUTER JOIN
相同的结果。我假设他们在SQL-92决定使用标准语法之前采用了他们的专有语法。
您使用标准SQL OUTER JOIN
语法(现在所有主要RDBMS实现都支持)显示的等效查询如下:
SELECT
Table1.Category1,
Table1.Category2,
COUNT(*) AS Total,
COUNT(Table2.Stat) AS Stat
FROM Table1
LEFT OUTER JOIN Table2 ON (Table1.PrimaryKey = Table2.ForeignKey)
GROUP BY Table1.Category1, Table1.Category2;
这意味着:
Table1
中的所有行都包含在查询结果中。Table2
中有匹配的行,请包含这些行(如果Table1
中有多个匹配的行,则重复Table2
的内容)。Table2
中没有匹配的行,请对查询结果中的所有NULL
列使用Table2
。答案 2 :(得分:5)
它是非ANSI左外连接表示法。从Oracle9i开始,使用'(+)'表示法的混淆外连接语法已被ISO 99外连接语法取代。
答案 3 :(得分:0)
值得注意的是,经典的Oracle表示法不直观,从代码清晰和可维护性的角度来看,最好避免使用它。
为说明这一点,我提供了此示例。
要在表LEFT outer join
和A
之间实现B
,可以期望左边的表A旁边应该有(+)运算符。正如我们要表示的那样,这将是有道理的,无论与B的连接条件是否成功,我们都将包括A的所有行。但是,事实并非如此,并且可以按以下方式实现连接
select b.age, a.name
from Employees a, EmployeeUNI b
where a.id = b.id(+)
我更喜欢显式的ANSI SQL版本:
select b.age, a.name
From Employees a
LEFT outer join EmployeeUNI b
on a.id = b.id
这两种方法都将产生相同的输出,但是ANSI方法不会带来新手程序员错误地将(+)放在错误位置的风险。