在我们正在迁移的基于 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 子句中做什么?我以前从未见过它这样使用过。
根据“=”的哪一侧,“(+)”表示左外连接或右外连接(在这种情况下,它是左外连接)。这是旧的 Oracle 语法,有时人们更喜欢谁先学会它,因为他们喜欢它使他们的代码更短。
为了可读性,最好不要使用它。
正如其他人所说,
(+)
语法是过时的专有语法,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
。这是一个非 ANSI 左外连接符号。从 Oracle9i 开始,使用“(+)”符号的令人困惑的外连接语法已被 ISO 99 外连接语法取代。
一个值得注意的考虑是,经典的 Oracle 表示法不直观,从代码清晰度和可维护性的角度最好避免使用。
为了说明这一点,我提供了这个例子。
为了在表
LEFT outer join
和 A
之间实现 B
,人们会期望左边的表 A 旁边应该有 (+) 运算符。这是有道理的,因为我们想表示我们将包括 A 的所有行,而不管与 B 的连接标准是否成功。然而情况并非如此,连接是按如下方式实现的
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 方法不会带来新手程序员错误地将 (+) 放在错误位置的风险。