Oralce连接运算符(+)

Oracle外连接除了常用的 LEFT|RIGHT|FULL [OUTER] JOIN 外,还有其特有的连接运算符(+)。但使用(+)运算符受以下限制:

  • 不能在包含FROM子句连接语法的查询块中使用(+)运算符。
  • (+)运算符只能出现在WHERE子句中,或者出现在FROM子句中左相关(指定TABLE子句时)的上下文中,并且只能应用于表或视图的列。
  • 如果A表和B表通过多个连接条件连接,则必须在所有的这些条件下使用(+)运算符。否则Oracle数据库将仅返回由简单连接产生的行,但没有警告或错误来告诉你这不是外连接的结果。
  • 如果在外部查询中指定一个表而在内部查询中指定另一个表,则(+)运算符不会生成外连接。
  • 尽管自连接是有效的,但是不能使用(+)运算符将表外连接到自身。例如,以下语句是无效的:

    1
    2
    3
    4
    -- 以下语句是无效的
    SELECT employee_id, manager_id
    FROM employees
    WHERE employees.manager_id(+) = employees.employee_id;

    但是以下自连接是有效的:

    1
    2
    3
    4
    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;
  • (+)运算符只能应用于列,而不能应用于任意表达式,但是,任意表达式可以包含一个或多个用(+)运算符标记的列。
  • 包含(+)运算符的WHERE条件不能与使用OR逻辑运算符的其他条件组合。
  • WHERE条件不能使用IN比较条件将标有(+)运算符的列与表达式进行比较。

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

在执行两个以上表对的外连接查询中,单个表可以是仅为一个其他表的null值表。因此,在A和B的连接条件以及B和C的连接条件中,不能将(+)运算符应用于B的列。

根据以上,我们可以将(+)语法转换回 LEFT|RIGHT|FULL [OUTER] JOIN 语法。

单条件:

1
2
select * from t_student s1, t_gender g1 where s1.gender=g1.gender_id(+);
select * from t_student s1 left join t_gender g1 on s1.gender=g1.gender_id;

多条件:

1
2
3
--t_student表先关联t_gender表,然后筛选出t_gender.gender_name='男'的记录
select * from t_student s1, t_gender g1 where s1.gender=g1.gender_id(+) and g1.gender_name='男';
select * from t_student s1 left join t_gender g1 on s1.gender=g1.gender_id where g1.gender_name='男';

1
2
3
--t_student表去关联t_gender表中t_gender.gender_name='男'的记录。
select * from t_student s1, t_gender g1 where s1.gender=g1.gender_id(+) and g1.gender_name(+)='男';
select * from t_student s1 left join t_gender g1 on s1.gender=g1.gender_id and g1.gender_name='男';

外连接无效:

1
2
select * from t_a a, t_b b where a.id(+)=b.id and a.code=b.code;
select * from t_a a, t_b b where a.id=b.id and a.code=b.code; -- 由于使用了(+)运算符,但不是所有条件都用了(+),对于Oracle来看其实是简单连接

参考:

Oracle Docs

Oracle左外连接、右外连接、完全外连接以及(+)号用法

Oracle中(+)连接写法解释