why do they use (+) in where clause for checking not null in a column eg emp_name(+) IS NOT NULL

时间:2015-06-25 10:01:54

标签: oracle

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

1 个答案:

答案 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的更改。