以下是摘自oracle ocp9i文档:
outer join syntax:
1)you use an outer join to also see rows that do not meet the join condition
2)the outer join operator is the plus sign(+)
outer join restrictions:
1)the outer join operator can appear on only one side of the expression:the side that has information missing.it returns those rows from one table that have no direct match in the other table.
2)a condition involving an outer join cannot use the IN operator or be linked to another condition by the OR operator.
配置实验环境:
hr@ORCL> drop table a;
hr@ORCL> drop table b;
hr@ORCL> create table a(id number,name varchar2(10));
hr@ORCL> create table b(id number,name varchar2(10));
hr@ORCL> insert into a values(1,'a');
hr@ORCL> insert into a values(2,'b');
hr@ORCL> insert into a values(3,'c');
hr@ORCL> insert into b values(1,'a');
hr@ORCL> insert into b values(2,'b');
hr@ORCL> insert into b values(4,'d');
hr@ORCL> select * from a;
ID NAME
---------- ----------
1 a
2 b
3 c
hr@ORCL> select * from b;
ID NAME
---------- ----------
1 a
2 b
4 d
hr@ORCL> commit;
--全外连接的结果是:
1)选出所有满足条件的结果
2)以左表为准,将左表不满足条件的结果接在左边
3)以右表为准,把右表不满足条件的结果接在右边
4)将以上结果全部合起来
hr@ORCL> select a.id,b.id from a full join b on a.id=b.id;
ID ID
---------- ----------
1 1
2 2
3
4
--left out join和oracle的加号在右结果是相同。同理,right out join和加号在左是一样的。(sql99的语法和oracle私有语法的比较)
hr@ORCL> select a.id,b.id from a,b where a.id=b.id(+);
ID ID
---------- ----------
1 1
2 2
3
hr@ORCL> select a.id,b.id from a left outer join b on a.id=b.id;
ID ID
---------- ----------
1 1
2 2
3
--结果类似于from a left join b on a.col=b.col and a.coln=....。单个列选择条件的列是基表(加号在谁身上谁是从表,没有加号的一方是基表)的用decode和+改写,不能用一般的改写,若不是基表的可以简单用+改写。比如:
SQL> SELECT a.ID,b.ID
2 FROM a FULL JOIN b
3 ON a.ID=b.ID AND a.NAME='a';
ID ID
---------- ----------
1 1
2
3
1 1
4
2
改写之:
SQL> SELECT a.ID,b.ID
2 FROM a,b WHERE a.id=decode(a.NAME,'a',b.ID(+))
3 UNION ALL
4 SELECT a.ID,b.ID
5 FROM a,b WHERE a.ID(+)=b.ID AND a.NAME(+)='a' AND a.ID IS NULL;
ID ID
---------- ----------
1 1
2
3
1 1
2
4
用union来实现上面例子的full join结果,需要考虑表的关系。
1)如果是两表1:1
加号在左,以右为准(相当于sql99的right join)
加号在右,以左为准(相当于sql99的left join)
即:在没加号的地方,读取前缀。
比如:where e.department_id(+)=d.department_id
读作:所有部门
hr@ORCL> select a.id,b.id from a,b where a.id=b.id(+)
2 union
3 select a.id,b.id from a,b where a.id(+)=b.id;
ID ID
---------- ----------
1 1
2 2
3
4
2)如果是两表1:n,用union剔重就不正确。
hr@ORCL> insert into a values(1,'a');
hr@ORCL> commit;
hr@ORCL> select * from a;
ID NAME
---------- ----------
1 a
2 b
3 c
1 a
hr@ORCL> select * from b;
ID NAME
---------- ----------
1 a
2 b
4 d
--1:n用UNION不正确
SQL> SELECT a.ID,b.ID
2 FROM a,b WHERE a.ID=b.ID(+)
3 UNION
4 SELECT a.ID,b.ID
5 FROM a,b WHERE a.ID(+)=b.ID;
ID ID
---------- ----------
1 1
2 2
3
4
--正确解法有三。注意,在使用sql时,任何时候,任何地方,一定要考虑null!!!切记。
法一:
SQL> SELECT a.ID,b.ID
2 FROM a,b WHERE a.ID=b.ID(+)
3 UNION ALL
4 SELECT a.ID,b.ID
5 FROM a,b WHERE a.ID(+)=b.ID AND a.ID IS NULL;
ID ID
---------- ----------
1 1
1 1
2 2
3
4
法二:
SQL> SELECT a.ID,b.ID
2 FROM a,b WHERE a.ID=b.ID(+) AND b.ID IS NULL
3 UNION ALL
4 SELECT a.ID,b.ID
5 FROM a,b WHERE a.ID(+)=b.ID;
ID ID
---------- ----------
3
1 1
1 1
2 2
4
法三:
SQL> SELECT a.ID,b.ID
2 FROM a FULL JOIN b
3 ON a.ID=b.ID;
ID ID
---------- ----------
1 1
1 1
2 2
3
4
--逗号和full join是不一样的。另外,full join须加上关键字on,才是完整的语句。
hr@ORCL> select p.id,t.id from p,t where p.id=t.id;
ID ID
---------- ----------
1 1
3 3
hr@ORCL> select p.id,t.id from p full join t on p.id=t.id;
ID ID
---------- ----------
1 1
3 3
2
5
全外连接和union连接都可以实现相同结果。我们来看一下他们的执行计划。
全外连接的执行计划:
hr@ORCL> select a.id,b.id from a full join b on a.id=b.id;
ID ID
---------- ----------
1 1
2 2
3
4
Execution Plan
----------------------------------------------------------
Plan hash value: 2192011130
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 104 | 13 (8)| 00:00:01 |
| 1 | VIEW | | 4 | 104 | 13 (8)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | HASH JOIN OUTER | | 3 | 312 | 7 (15)| 00:00:01 |
| 4 | TABLE ACCESS FULL| A | 3 | 195 | 3 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| B | 3 | 117 | 3 (0)| 00:00:01 |
|* 6 | HASH JOIN ANTI | | 1 | 26 | 7 (15)| 00:00:01 |
| 7 | TABLE ACCESS FULL| B | 3 | 39 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL| A | 3 | 39 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."ID"="B"."ID"(+))
6 - access("A"."ID"="B"."ID")
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
29 consistent gets
0 physical reads
0 redo size
520 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
4 rows processed
union的执行计划:
hr@ORCL> select a.id,b.id from a,b where a.id=b.id(+)
2 union
3 select a.id,b.id from a,b where a.id(+)=b.id;
ID ID
---------- ----------
1 1
2 2
3
4
Execution Plan
----------------------------------------------------------
Plan hash value: 891669117
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 156 | 15 (60)| 00:00:01 |
| 1 | SORT UNIQUE | | 6 | 156 | 15 (60)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | HASH JOIN OUTER | | 3 | 78 | 7 (15)| 00:00:01 |
| 4 | TABLE ACCESS FULL| A | 3 | 39 | 3 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| B | 3 | 39 | 3 (0)| 00:00:01 |
|* 6 | HASH JOIN OUTER | | 3 | 78 | 7 (15)| 00:00:01 |
| 7 | TABLE ACCESS FULL| B | 3 | 39 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL| A | 3 | 39 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."ID"="B"."ID"(+))
6 - access("A"."ID"(+)="B"."ID")
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
520 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
4 rows processed
显然,union连接的cpu代价要比full join连接来得多。此外,union还会暗含一个排序操作。当数据量海量时,估计会对性能带来一定的影响。而且,在oracle的私有语法里,是没有全外连接的,只能通过union连接来模拟full join。所以,建议需要使用外连接时,请使用full join,不要用union模拟。
分享到:
相关推荐
ORACLE的优化器共有3种 ... 在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器
缺省情况下是inner join,开发中使用的left join和right join属于outer join,另外outer join还包括full join.下面我通过图标让大家认识它们的区别。 现有两张表,Table A 是左边的表。Table B 是右边的表。其各有四条...
sql练习中易错笔记,order by ,group by,distinct,内连接,外连接等,一些mysql和oracle使用的区别:sql4种连接 两个表中有相同的列,根据共有的列值匹配行 left join左外连接,不管左表是否在右表中有匹配行,都...
连接无非是这几个 --内连接和where相同 inner join ... left join --右向外连接, right join --完整外部连接, full join --交叉连接,也称笛卡儿积。 cross join .......
[LEFT | RIGHT | FULL OUTER JOIN 表名称2]; 1. 交叉连接:CROSS JOIN,主要功能是产生笛卡儿积,简单实现多表查询; SELECT * FROM emp CROSS JOIN dept; 2. 自然连接:NATURAL JOIN,自动使用关联字段消除...
内连接(inner join)和外连接(left join/right join/full join) 排序(Order By) 条件(Where) 分组(Group By) 分组条件(Having) 计算字段 SQL查询表 SQL查询子句 丰富的函数 表别名 字段别名 联合(Union...
3.7.1 SQL 92 标准:Inner Join、Left Join、Right Join、Full Join, 3.7.2 特殊语法:*=、=*、*=*(MS_SQL,Sybase),(+)(Oracle) 3.8 联合 (Union [All],Minus,Intersect) 3.9 字段别名,数据表别名 ...
ORACLE用户是学习ORACLE数据库中的基础知识,下面就介绍下类系统常用的默认ORACLE用户: 1. sys用户:超级用户,完全是个SYSDBA(管理数据库的人)。拥有dba,sysdba,sysoper等角色或权限。是oracle权限最高的用户,...
外连接: 全连接(full join)、左连接(left join)、右连接(right join)。 交叉联接(cross join)。 外连接与内连接不一样,外连接返回的查询结果中不仅包含符合条件的行,还包括左表(左外连接),右表(右外连接)...
3.7.1 SQL 92 标准:Inner Join、Left Join、Right Join、Full Join, 3.7.2 特殊语法:*=、=*、*=*(MS_SQL,Sybase),(+)(Oracle) 3.8 联合 (Union [All],Minus,Intersect) 3.9 字段别名,数据表别名 ...
对于外连接,Oracle中可以使用“(+)”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN,下面将配合实例一一介绍。
一些数据库,如SQL Server, Oracle和DB2也支持JOIN HINT关键字的概念。这些关键字被插入到JOIN声明中来控制JOIN被处理的顺序。例如,一个MERGE JOIN会在处理其他连接之前将两个表格连接在一起。HASH JOIN会将一个...
实例参考如下: SQL的Join语法有很多, inner join(等值连接) 只返回两个表中联结字段相等的⾏, left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录, right join(右联接) 返回包括右表中的...
这是我个人通过长时间的实践与收集最后总结出来的基本关系表的连接操作实际应用,以及在某些情况下可以用普通的sql语句代替某些连接操作(即实现同样的功能)其中文件夹中已经...ORACLE数据库直接用PL/SQL 导入就可。
from student_A A full outer join student_B B on A.Uuid = B.Uuid; 1.6.4.3 结果 1.6.4.4 全外连接不支持(+)写法 1.6.5 (+) + 表示补充,即哪个表有加号,这个表就是匹配表。 1.7 运算符 1.7.1 比较 =、>,<,...
以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。 ------------------------------------------------------------- Recordset属性 adOpenForwardOnly adOpenKeyset ...
select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... 12、说明:日程安排提前五分钟提醒 SQL: select * from 日程安排 where datediff('minute',f...
user and multi-user mode Full transactions support with ReadCommited isolation level SQL Support SELECT with DISTINCT, INNER LEFT, RIGTH, FULL and OUTER JOIN, GROUP BY and ORDER BY clauses CREATE ...
select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... 12、说明:日程安排提前五分钟提醒 SQL: select * from 日程安排 where datediff('minute',f...
select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... 12、说明:日程安排提前五分钟提醒 SQL: select * from 日程安排 where datediff('minute',f...