1

我必须比较两个具有相同结构的表(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)

当其中任何一个(t1 或 t2)中的 field3 为 NULL 时,查询不会返回任何行。例如,我想从该数据中返回一行,但它什么也没返回。

表格1

field1    field2    field3
1         2         <NULL>

表 2

field1    field2    field3
1         2         'some text data' 

使用 NVL 函数可以解决此类问题: NVL(field3, 'dummytextorwhatever')但我不想在我的代码中包含如此可怕的东西。有什么想法可以用可空字段解决这个问题吗?

谢谢!

4

4 回答 4

4

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

“当写WHERE value NOT IN (x, y, z)这将被内部解释为WHERE value != x AND value != y AND value != z,并且比较NULL(无论是平等还是不平等)总是产生FALSE

简单的答案是使用 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

“为什么一开始就选择一个null?”

因为 NOT EXISTS 子查询返回什么并不重要。重要的是它返回一个非空的结果集。它可能是1field1但它真的不重要,那为什么不null呢?

于 2017-05-02T09:44:14.047 回答
1

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

Select t1.field1, t1.field2, t1.field3
From   table1 t1
Minus
select t2.field1, t2.field2, t2.field3
from   table2 t2; 
于 2017-05-02T14:28:09.210 回答
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      
于 2017-05-02T09:43:43.377 回答
1

尝试使用NVLorCoalesce运算符,像这样

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 选择将返回该行,因为nvl(field1,0)=nvl(field2,0)field1=0field2=null,所以你可以使用任何值(你应该有信心),例如在你的表数据中不存在-99(nvl(field,-99))

或者你可以使用存在/不存在

于 2017-05-02T09:46:05.953 回答