代码之家  ›  专栏  ›  技术社区  ›  Jonathan Lonowski

甲骨文:“(+)”在WHERE子句中做什么?

  •  53
  • Jonathan Lonowski  · 技术社区  · 17 年前

    在我们正在迁移的基于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
    

    什么是 (+)

    3 回复  |  直到 16 年前
        1
  •  96
  •   SquareCog    17 年前

    根据“=”的哪一侧,“+”表示左外连接或右外连接(在本例中,它是左外连接)。这是一种古老的Oracle语法,有时最先学习它的人更喜欢它,因为他们喜欢它使代码更短。

    为了可读性,最好不要使用它。

        2
  •  25
  •   Bill Karwin    17 年前

    正如其他人所指出的那样 (+) 语法是过时的专有语法,Oracle多年来一直使用这种语法来实现与 OUTER JOIN

    与您显示的查询相同的查询,使用标准SQL 外接

    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 表1 如果中有多个匹配行 ).
    • 表2 使用 NULL 为了所有人 表2
        3
  •  5
  •   Otávio Décio    17 年前

    这是一个非ANSI左外连接符号。从Oracle9i开始,使用(+)符号的混乱外部连接语法已被ISO 99外部连接语法所取代。

        4
  •  3
  •   Captain Jack Sparrow tonysok    6 年前

    值得注意的是,经典的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方法不会带来新手程序员错误地将(+)放在错误位置的风险。