使用Oracle 11g中的+符号左外连接

Mik*_*ike 79 sql oracle11g

任何人都可以告诉我下面的2个查询是左外连接还是右外连接的例子?

Table Part:
Name         Null?       Type
PART_ID      NOT NULL    VARCHAR2(4)
SUPPLIER_ID              VARCHAR2(4)

PART_ID SUPPLIER_ID
P1      S1
P2      S2
P3  
P4  

Table Supplier:
Name            Null?     Type
SUPPLIER_ID NOT NULL      VARCHAR2(4)
SUPPLIER_NAME   NOT NULL  VARCHAR2(20)

SUPPLIER_ID  SUPPLIER_NAME
S1           Supplier#1
S2           Supplier#2
S3           Supplier#3
Run Code Online (Sandbox Code Playgroud)

显示所有零件,无论供应商是否供货:

SELECT P.Part_Id, S.Supplier_Name
FROM Part P, Supplier S
WHERE P.Supplier_Id = S.Supplier_Id (+)

SELECT P.Part_Id, S.Supplier_Name
FROM Part P, Supplier S
WHERE S.Supplier_Id (+) = P.Supplier_Id

Wis*_*guy 182

TableA LEFT OUTER JOIN TableB相当于TableB RIGHT OUTER JOIN Table A.

在Oracle中,(+)表示JOIN中的"可选"表.所以在你的第一个查询中,它是一个P LEFT OUTER JOIN S.在你的第二个查询中,它是S RIGHT OUTER JOIN P.它们在功能上是等同的.

在术语中,RIGHT或LEFT指定连接的哪一侧始终具有记录,而另一侧可能为空.所以在a中P LEFT OUTER JOIN S,P将始终有一个记录,因为它在LEFT,但S可能是null.

有关其他说明,请参阅java2s.com中的此示例.


为了澄清,我想我说这个术语并不重要,因为它只是帮助可视化.重要的是你了解它的工作原理.


右与左

我已经看到在隐式连接语法中确定RIGHT vs LEFT的重要性时会有些困惑.

LEFT OUTER JOIN

SELECT *
FROM A, B
WHERE A.column = B.column(+)
Run Code Online (Sandbox Code Playgroud)

正确加入

SELECT *
FROM A, B
WHERE B.column(+) = A.column
Run Code Online (Sandbox Code Playgroud)

我所做的只是在WHERE子句中交换术语的两侧,但它们在功能上仍然是等价的.(有关详细信息,请参阅我的答案中的更高位置.)(+)确定RIGHT或LEFT的位置.(具体来说,如果(+)它在右边,那么它是一个LEFT JOIN.如果(+)在左边,它是一个正确的连接.)


JOIN的类型

JOIN的两种样式是隐式JOIN显式JOIN.它们是编写JOIN的不同风格,但它们在功能上是等价的.

看到这个问题.

隐式JOIN只是将所有表一起列出.连接条件在WHERE子句中指定.

隐含的JOIN

SELECT *
FROM A, B
WHERE A.column = B.column(+)
Run Code Online (Sandbox Code Playgroud)

显式JOIN将连接条件与特定表的包含关联,而不是在WHERE子句中.

明确的加入

SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column
Run Code Online (Sandbox Code Playgroud)

这些隐式JOIN可能更难以阅读和理解,并且它们也有一些限制,因为连接条件在其他WHERE条件中混合.因此,通常建议使用隐式JOIN来支持显式语法.

  • 是的,我现在得到它 - JOIN是由(+)的存在隐式创建的.凉. (2认同)
  • @Mike:这就是+语法的工作方式.它意味着"可选",因此请将其读作"列出所有零件,可选择使供应商匹配". (2认同)
  • @Mike:只要你知道你在选择什么,你怎么称呼它并不重要.但请帮自己一个忙,而是使用惯用的`JOIN`语法!然后没有混淆的余地. (2认同)
  • “(+)”位于生成空值子行的表列上。 (2认同)

Rah*_*hul 8

这两个查询正在执行OUTER JOIN.见下文

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

  • 您不能在同样包含FROM子句连接语法的查询块中指定(+)运算符.

  • (+)运算符只能出现在WHERE子句中,或者出现在FROM子句中左对齐(指定TABLE子句时)的上下文中,并且只能应用于表或视图的列.

  • 如果A和B通过多个连接条件连接,则必须在所有这些条件中使用(+)运算符.如果不这样做,那么Oracle数据库将仅返回由简单连接产生的行,但没有警告或错误,建议您没有外连接的结果.

  • 如果在外部查询中指定一个表而在内部查询中指定另一个表,则(+)运算符不会生成外部联接.

  • 虽然自联接有效,但您不能使用(+)运算符将表外连接到自身.例如,以下语句无效:

    -- The following statement is not valid:
    SELECT employee_id, manager_id
       FROM employees
       WHERE employees.manager_id(+) = employees.employee_id;
    
    Run Code Online (Sandbox Code Playgroud)

    但是,以下自联接有效:

    SELECT e1.employee_id, e1.manager_id, e2.employee_id
       FROM employees e1, employees e2
       WHERE e1.manager_id(+) = e2.employee_id
       ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
    
    Run Code Online (Sandbox Code Playgroud)
  • (+)运算符只能应用于列,而不能应用于任意表达式.但是,任意表达式可以包含一个或多个用(+)运算符标记的列.

  • 包含(+)运算符的WHERE条件不能与使用OR逻辑运算符的其他条件组合.

  • WHERE条件不能使用IN比较条件将标有(+)运算符的列与表达式进行比较.

如果WHERE子句包含将表B中的列与常量进行比较的条件,则必须将(+)运算符应用于该列,以便Oracle从表A返回已为此列生成空值的行.否则,Oracle仅返回简单连接的结果.

在执行两个以上表对的外连接的查询中,单个表可以是仅针对另一个表的空生成表.因此,在A和B的连接条件以及B和C的连接条件中,不能将(+)运算符应用于B的列.有关外连接的语法,请参阅SELECT.

取自http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm