Why do we use a (+) operator in the where clause for instance emp_name(+) IS NOT NULL, emp_name IS NOT NULL AND emp_name(+) IS NOT NULL is the same
答案 0 :(得分:1)
因为从列中删除(+)而不是null,所以将连接从外连接转换为实际上是内连接的连接。离开(+)告诉oracle从" main"获取所有行。表,然后匹配外部联接表中该列不为空的任何行。
请参阅以下内容,了解" extra" (+)是必需的:
with t1 as (select 1 id, 'a' val from dual union all
select 2 id, 'b' val from dual union all
select 3 id, 'c' val from dual),
t2 as (select 1 id, null val from dual union all
select 3 id, 'd' val from dual)
select *
from t1,
t2
where t1.id = t2.id (+)
and t2.val (+) is not null
order by t1.id;
ID VAL ID_1 VAL_1
---------- --- ---------- -----
1 a
2 b
3 c 3 d
with t1 as (select 1 id, 'a' val from dual union all
select 2 id, 'b' val from dual union all
select 3 id, 'c' val from dual),
t2 as (select 1 id, null val from dual union all
select 3 id, 'd' val from dual)
select *
from t1,
t2
where t1.id = t2.id (+)
and t2.val is not null
order by t1.id;
ID VAL ID_1 VAL_1
---------- --- ---------- -----
3 c 3 d
如果将查询转换为ANSI连接语法,则可以更轻松地看到差异:
with t1 as (select 1 id, 'a' val from dual union all
select 2 id, 'b' val from dual union all
select 3 id, 'c' val from dual),
t2 as (select 1 id, null val from dual union all
select 3 id, 'd' val from dual)
select *
from t1
left outer join t2 on (t1.id = t2.id and t2.val is not null)
order by t1.id;
ID VAL ID_1 VAL_1
---------- --- ---------- -----
1 a
2 b
3 c 3 d
with t1 as (select 1 id, 'a' val from dual union all
select 2 id, 'b' val from dual union all
select 3 id, 'c' val from dual),
t2 as (select 1 id, null val from dual union all
select 3 id, 'd' val from dual)
select *
from t1
left outer join t2 on (t1.id = t2.id)
where t2.val is not null
order by t1.id;
ID VAL ID_1 VAL_1
---------- --- ---------- -----
3 c 3 d
换句话说," col之间的差异不是空的"谓词是外连接条件的一部分,或者是where子句中的过滤器。
您还要注意," t2.val不为空"在where子句中具有将外连接转换为内连接的效果,尽管您已请求外连接:
with t1 as (select 1 id, 'a' val from dual union all
select 2 id, 'b' val from dual union all
select 3 id, 'c' val from dual),
t2 as (select 1 id, null val from dual union all
select 3 id, 'd' val from dual)
select *
from t1
left outer join t2 on (t1.id = t2.id)
--where t2.val is not null
order by t1.id;
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | O/1/M |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 12 (100)| | | | |
| 1 | SORT ORDER BY | | 3 | 33 | 12 (17)| 00:00:01 | 2048 | 2048 | 1/0/0|
|* 2 | HASH JOIN OUTER| | 3 | 33 | 11 (10)| 00:00:01 | 1156K| 1156K| 1/0/0|
| 3 | VIEW | | 3 | 18 | 6 (0)| 00:00:01 | | | |
| 4 | UNION-ALL | | | | | | | | |
| 5 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 6 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 7 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 8 | VIEW | | 2 | 10 | 4 (0)| 00:00:01 | | | |
| 9 | UNION-ALL | | | | | | | | |
| 10 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 11 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
-----------------------------------------------------------------------------------------------------
with t1 as (select 1 id, 'a' val from dual union all
select 2 id, 'b' val from dual union all
select 3 id, 'c' val from dual),
t2 as (select 1 id, null val from dual union all
select 3 id, 'd' val from dual)
select *
from t1
left outer join t2 on (t1.id = t2.id)
where t2.val is not null
order by t1.id;
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | O/1/M |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 10 (100)| | | | |
| 1 | SORT ORDER BY | | 1 | 11 | 10 (20)| 00:00:01 | 2048 | 2048 | 3/0/0|
|* 2 | HASH JOIN | | 1 | 11 | 9 (12)| 00:00:01 | 1156K| 1156K| 3/0/0|
| 3 | VIEW | | 2 | 10 | 2 (0)| 00:00:01 | | | |
| 4 | UNION-ALL | | | | | | | | |
|* 5 | FILTER | | | | | | | | |
| 6 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 7 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 8 | VIEW | | 3 | 18 | 6 (0)| 00:00:01 | | | |
| 9 | UNION-ALL | | | | | | | | |
| 10 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 11 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
| 12 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | | |
-----------------------------------------------------------------------------------------------------
注意第二个解释计划中id = 2的行中从HASH JOIN OUTER到HASH JOIN的更改。