Oracle NOT IN不起作用将是可空字段

时间:2017-05-02 09:34:11

标签: sql oracle null nvl

我必须比较具有相同结构的两个表(int not null,int not null,varchar2)。在这两个表中field3都是可以为空的。

我有下一个SQL:

Select 
   t1.field1, t1.field2, t1.field3)  
From
   table1 t1
Where  (field1,field2,field3)
   not in 
   (select field1,
    field2,field3
    from table2 t2)

当field3在其中任何一个(t1或t2)中为NULL时,查询不返回任何行。例如,我想从这些数据中返回一行,但它根本不返回任何内容。

表1

field1    field2    field3
1         2         <NULL>

表2

field1    field2    field3
1         2         'some text data' 

有一种解决方法可以通过使用NVL函数来解决这个问题:NVL(field3, 'dummytextorwhatever')但我不想在我的代码中加入这样可怕的东西。有没有想法用可空字段来解决这个问题?

谢谢!

4 个答案:

答案 0 :(得分:4)

当主表或子查询的结果集中存在空值时,这是NOT IN的已知行为。正如@DrCopyPaste所说的那么好

  

&#34;在撰写WHERE value NOT IN (x, y, z)时,这将在内部被解释为WHERE value != x AND value != y AND value != z,并且与NULL进行比较(无论是相等还是不等),总是会产生FALSE&# 34;

简单的答案是使用NOT EXISTS:

Select 
   t1.field1, t1.field2, t1.field3)  
From
   table1 t1
Where  not exists   
   (select  null   from table2 t2
    where t2.field1 = t1.field1
    and t2.field2 = t1.field2
    and t2.field3 = t1.field3 )

反连接会产生相同的结果

Select 
   t1.field1, t1.field2, t1.field3)  
From
   table1 t1
     left join table2 t2
       on t2.field1 = t1.field1
       and t2.field2 = t1.field2
       and t2.field3 = t1.field3 
where t2.field1 is null
  

&#34;为什么在开头选择空?&#34;

因为使用NOT EXISTS,子查询返回的内容并不重要。重要的是它返回一个非空的结果集。可能是1field1但它确实无关紧要,为什么不null

答案 1 :(得分:1)

尝试not exists

Select 
  t1.field1, 
  t1.field2, 
  t1.field3
From
  table1 t1
where not exists 
  (select 1
    from table2 t2
  where 
  t1.field1=t2.field1 
  and t1.field2=t2.field2 
  and t1.field3=t2.field3
  )

样本测试

with table1(field1,field2,field3) as
(select 1,2,null from dual),
        table2(field1,field2,field3) as
(select 1,2,'something' from dual)

Select 
  t1.field1, 
  t1.field2, 
  t1.field3
From
  table1 t1
where not exists 
  (select 1
    from table2 t2
  where 
  t1.field1=t2.field1 
  and t1.field2=t2.field2 
  and t1.field3=t2.field3
  )

输出

FIELD1 FIELD2 FIELD3
1      2      

答案 2 :(得分:1)

尝试使用NVLCoalesce运算符,例如

Select 
   t1.field1, t1.field2, t1.field3 
From
   table1 t1
Where  (nvl(field1,0),nvl(field2,0),nvl(field3,0))
   not in 
   (select nvl(field1,0),nvl(field2,0),nvl(field3,0)
    from table2 t2)

但是如果在表数据中有一些数据等于0,则select将返回该行,因为nvl(field1,0)=nvl(field2,0)field1=0field2=null时,所以你可以使用任何值(你应该是信心 )您的表数据中不存在例如-99(nvl(field,-99))

或者你可以使用exists / not exists

答案 3 :(得分:1)

根据您的查询,您试图在table1中找到table2中不存在的所有时间。而不是NOT IN,考虑使用MINUS ......

Select t1.field1, t1.field2, t1.field3
From   table1 t1
Minus
select t2.field1, t2.field2, t2.field3
from   table2 t2;