Oracle:左连接、右连接、全外连接、(+)号详解

目录

Oracle 左连接、右连接、全外连接、(+)号详解

1、左外连接(LEFT OUTER JOIN/ LEFT JOIN)

2、右外连接(RIGHT OUTER JOIN/RIGHT JOIN)

3、全外连接(FULL OUTER JOIN/FULL JOIN)

4、补充

5、Oracle中 (+)与left join 的用法区别


Oracle 左连接、右连接、全外连接、(+)号详解

Oracle 外连接 (OUTER JOIN) 分为三种 : 左外连接,右外连接,全外连接。left join、right join 和 join 的区别如下:

  • 左外连接(左边的表不加限制)
  • 右外连接(右边的表不加限制)
  • 全外连接(左右两表都不加限制)
  • 连接(左右两表交集)

对应SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常省略OUTER关键字, 写成:LEFT/RIGHT/FULL JOIN。

在左连接和右连接时都会以一张表为基础表,另一张表为补充表,基础表的内容会全部显示,然后再加上两张表匹配的内容。 如果基础表的数据在补充表中没有记录, 那么在相关联的结果集行中补充表列显示为空值(NULL)。

对于外连接, 也可以使用"(+) "来表示。 关于使用(+)的一些注意事项:

  1. (+)操作符只能出现在 WHERE 子句中,并且不能与 OUTER JOIN 语法同时使用。
  2. 当使用(+)操作符执行外连接时,如果在WHERE子句中包含有多个条件,则必须在所有条件中都包含(+)操作符。
  3. (+)操作符只适用于列,而不能用在表达式上。
  4. (+)操作符不能与 OR 和 IN 操作符一起使用。
  5. (+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。

开始前,先创建两张表,插入数据便于理解测试:

|----------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | CREATE TABLE A ( id number, name VARCHAR2(10) ); CREATE TABLE B ( id number, name VARCHAR2(10) ); INSERT INTO A VALUES(1,'A1'); INSERT INTO A VALUES(1,'A2'); INSERT INTO A VALUES(2,'B1'); INSERT INTO A VALUES(3,'C1'); INSERT INTO A VALUES(4,'D1'); INSERT INTO B VALUES(1,'AA'); INSERT INTO B VALUES(1,'BB'); INSERT INTO B VALUES(2,'CC'); INSERT INTO B VALUES(6,'DD'); |

1、左外连接(LEFT OUTER JOIN/ LEFT JOIN)

LEFT JOIN 是以左表的记录为基础表,右表的记录为补充表,示例中A表可以看成左表,B表可以看成右表,它的结果集是A表中的全部数据,再加上A表和B表匹配后的数据。换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录。A表有B表没有的记录对应的B表列显示为NULL。

|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 | SQL> select * from A a left join B b on a.id = b.id; ID NAME ID NAME --------------- --------------- --------------- --------------- 1 A2 1 AA 1 A1 1 AA 1 A2 1 BB 1 A1 1 BB 2 B1 2 CC 4 D1 3 C1 |

用(+)来实现, 这个 + 号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。如果加号写在右表,左表就是全部显示,所以是左连接。

|---|--------------------------------------------|
| 1 | select * from A a,B b where a.id=b.id(+); |

2、右外连接(RIGHT OUTER JOIN/RIGHT JOIN)

和LEFT JOIN的结果刚好相反,是以右表(B)为基础的。它的结果集是B表所有记录,再加上A和B匹配后的数据。 A表记录不足的地方均为NULL。

|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 | SQL> select * from A a right join B b on a.id = b.id; ID NAME ID NAME --------------- --------------- --------------- --------------- 1 A1 1 BB 1 A1 1 AA 1 A2 1 BB 1 A2 1 AA 2 B1 2 CC 6 DD |

用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。如果加号写在左表,右表就是全部显示,所以是右连接。

|---|--------------------------------------------|
| 1 | select * from A a,B b where a.id(+)=b.id; |

3、全外连接(FULL OUTER JOIN/FULL JOIN)

左表和右表都不做限制,所有的记录都显示,两表不足的地方均为NULL。 全外连接不支持(+)写法。

|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 | SQL> select * from A a full join B b on a.id = b.id; ID NAME ID NAME --------------- --------------- --------------- --------------- 1 A1 1 BB 1 A1 1 AA 1 A2 1 BB 1 A2 1 AA 2 B1 2 CC 3 C1 4 D1 6 DD |

4、补充

|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 | SQL> select * from A a,B b where a.id = b.id; ID NAME ID NAME --------------- --------------- --------------- --------------- 1 A1 1 BB 1 A1 1 AA 1 A2 1 BB 1 A2 1 AA 2 B1 2 CC |

|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 | SQL> select * from A a join B b on a.id = b.id; ID NAME ID NAME --------------- --------------- --------------- --------------- 1 A1 1 BB 1 A1 1 AA 1 A2 1 BB 1 A2 1 AA 2 B1 2 CC |

|---------------|-----------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 | SQL> select * from A a where a.id in (select b.id from B b); ID NAME --------------- --------------- 1 A2 1 A1 2 B1 |

|---------------|-------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 | SQL> select * from A a where exists (select 1 from B b where a.id = b.id); ID NAME --------------- --------------- 1 A2 1 A1 2 B1 |

5、Oracle中 (+)与left join 的用法区别

1. (+) 写在 where 后面,不能与 or/in 连用, a表是主表,b表是附属表。

select * from a,b where a.id=b.id(+);

2. 左连接写在 from 与where之间,a left join b on a.id=b.id :主表a left join 附表b on 连接条件。

select * from a left join b on a.id=b.id;

3.效率上没区别,left join 可读性高、功能更全面、通用性强、而且是新标准,建议使用left join。

相关推荐
睿思达DBA_WGX3 小时前
由 DB_FILES 参数导致的 dg 服务器无法同步问题
运维·数据库·oracle
袋鼠云数栈4 小时前
使用自然语言体验对话式MySQL数据库运维
大数据·运维·数据库·后端·mysql·ai·数据治理·数栈·data+ai
阿里云大数据AI技术4 小时前
数据 + 模型 驱动 AI Native 应用发展
大数据·数据库·人工智能
??? Meggie5 小时前
【SQL】使用UPDATE修改表字段的时候,遇到1054 或者1064的问题怎么办?
android·数据库·sql
一屉大大大花卷5 小时前
初识Neo4j之图数据库(二)
数据库·neo4j
天翼云开发者社区5 小时前
OLAP分析数据库适用场景及主流产品对比
数据库
Britz_Kevin5 小时前
从零开始的云计算生活——番外2,MySQL组复制
数据库·mysql·云计算·生活·#组复制
工藤学编程6 小时前
分库分表之实战-sharding-JDBC绑定表配置实战
数据库·分布式·后端·sql·mysql
老纪的技术唠嗑局6 小时前
单机分布式一体化数据库的架构设计与优化
数据库·分布式
GBASE7 小时前
“G”术时刻:Linux环境下通过ESQL/C方式连接南大通用GBase 8s数据库(上)
数据库