Oracle NOT IN 对可为空的字段不起作用
Oracle NOT IN does not work will nullable fields
我必须比较两个具有相同结构的表(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)
当字段 3 在其中任何一个(t1 或 t2)中为 NULL 时,查询不会 return 任何行。例如,我想从该数据中 return 一行,但 return 什么都没有。
Table 1
field1 field2 field3
1 2 <NULL>
Table 2
field1 field2 field3
1 2 'some text data'
使用 NVL 函数可以解决此类问题:NVL(field3, 'dummytextorwhatever')
但我不想在我的代码中包含这种可怕的东西。有解决此问题的想法吗?
谢谢!
尝试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
当主 table 或子查询的结果集中存在空值时,这是 NOT IN 的已知行为。正如@DrCopyPaste 所说的那样
"when writing WHERE value NOT IN (x, y, z)
this will be internally interpreted as WHERE value != x AND value != y AND value != z
, and comparing against NULL
(either for equality or unequality) always yields 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
"why do you select a null at the beginning?"
因为对于 NOT EXISTS,子查询是什么并不重要 returns。重要的是它 returns 一个非空结果集。它可能是 1
或 field1
,但这真的无关紧要,所以为什么不是 null
?
尝试使用 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 将是 return 那一行,因为 nvl(field1,0)=nvl(field2,0)
当 field1=0
和 field2=null
时,所以你可以使用任何值(你应该有信心
) 您的表格数据中不存在,例如 -99(nvl(field,-99))
或者您可以使用 exists/not exists
根据您的查询,您试图在表 1 中查找表 2 中不存在的所有时间。考虑使用 MINUS 而不是 NOT IN...
Select t1.field1, t1.field2, t1.field3
From table1 t1
Minus
select t2.field1, t2.field2, t2.field3
from table2 t2;
我必须比较两个具有相同结构的表(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)
当字段 3 在其中任何一个(t1 或 t2)中为 NULL 时,查询不会 return 任何行。例如,我想从该数据中 return 一行,但 return 什么都没有。
Table 1
field1 field2 field3
1 2 <NULL>
Table 2
field1 field2 field3
1 2 'some text data'
使用 NVL 函数可以解决此类问题:NVL(field3, 'dummytextorwhatever')
但我不想在我的代码中包含这种可怕的东西。有解决此问题的想法吗?
谢谢!
尝试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
当主 table 或子查询的结果集中存在空值时,这是 NOT IN 的已知行为。正如@DrCopyPaste 所说的那样
"when writing
WHERE value NOT IN (x, y, z)
this will be internally interpreted asWHERE value != x AND value != y AND value != z
, and comparing againstNULL
(either for equality or unequality) always yieldsFALSE
"
简单的答案是使用 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
"why do you select a null at the beginning?"
因为对于 NOT EXISTS,子查询是什么并不重要 returns。重要的是它 returns 一个非空结果集。它可能是 1
或 field1
,但这真的无关紧要,所以为什么不是 null
?
尝试使用 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 将是 return 那一行,因为 nvl(field1,0)=nvl(field2,0)
当 field1=0
和 field2=null
时,所以你可以使用任何值(你应该有信心
) 您的表格数据中不存在,例如 -99(nvl(field,-99))
或者您可以使用 exists/not exists
根据您的查询,您试图在表 1 中查找表 2 中不存在的所有时间。考虑使用 MINUS 而不是 NOT IN...
Select t1.field1, t1.field2, t1.field3
From table1 t1
Minus
select t2.field1, t2.field2, t2.field3
from table2 t2;