我必须比较具有相同结构的两个表(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')
但我不想在我的代码中加入这样可怕的东西。有没有想法用可空字段来解决这个问题?
谢谢!
答案 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,子查询返回的内容并不重要。重要的是它返回一个非空的结果集。可能是1
或field1
但它确实无关紧要,为什么不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)
尝试使用NVL
或Coalesce
运算符,例如
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=0
和field2=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;