sql比较带有一些空值的字段

sql比较带有一些空值的字段,sql,oracle,Sql,Oracle,如果字段1中的值不等于字段2中的值(其中字段2包含一些空值),我将尝试在Oracle SQL中编写一个查询以返回行 如果桌子看起来像这样 Field1 Field2 1 1 2 3 4 如果我使用此查询: select * from table where field1 != field2 我只返回第2行,而不是第3行。是否有一个查询可以用于检索两行2、3?如果字段2为NULL,则还包括该字段。您知道NULL不是匹配项,但希望显示它 S

如果字段1中的值不等于字段2中的值(其中字段2包含一些空值),我将尝试在Oracle SQL中编写一个查询以返回行

如果桌子看起来像这样

Field1    Field2
1         1
2         3
4         
如果我使用此查询:

select * from table where field1 != field2

我只返回第2行,而不是第3行。是否有一个查询可以用于检索两行2、3?

如果
字段2
NULL
,则还包括该字段。您知道NULL不是匹配项,但希望显示它

SELECT * FROM table 
WHERE field1 != field2
    OR (field1 IS NULL AND field2 IS NOT NULL)
    OR (field1 IS NOT NULL AND field2 IS NULL)
此外,您可以使用
COALESCE
null
断言为另一个值。在本例中,我使用了0。只有当
field1
field2
没有0时,才使用0。基本上选择一个不会出现在表中的值

select * from table where COALESCE(field1, 0) != COALESCE(field2, 0)
编辑:OP断言field1可以为空,所以我更改了第一个查询。查询1更清楚地说明了发生了什么,查询2更简洁地实现了相同的最终结果

请在此处阅读更多信息:

您也可以使用
NVL()
来处理
NULL
之类的
COALESCE
,但据我所知效率较低。更多信息:

如果要排除两个字段均为
NULL
的行(如您在注释中所示),则可以使用

select *
from   <table>
where  decode(field1, field2, 1, 0) = 0
;
选择*
从…起
其中解码(字段1,字段2,1,0)=0
;

这利用了
decode
的特殊定义。如果
field1=field2
,并且当它们都
null
(与SQL中
null
的“正确”处理相反)时,它返回第三个参数(在本例中为1)。在所有其他情况下,它返回0,这是您想要的。

您好,这里已经有一些正确答案,但这里有另一个您可能更喜欢的答案:

select * from table where field1 != nvl(field2,-field1);
让我们知道它是否适用于您。如需进一步澄清,请随时再次询问我


Ted

您可以使用case语句来测试所需语句中的相等性。此表达式的计算结果永远不会为null,因此可以安全地将not应用于该表达式,并获得互补行

select * from my_table
where 
not case 
  when field1=field2 then 1
  when field1 is null and field2 is null then 1
  else 0
end = 1;

谢谢,我明白了,但我想知道为什么这是必要的?如果其中一个字段为空,field1不等于field2,这不是毫无疑问的事实吗?这很挑剔,但这不能处理它们都为空的情况,或者field1为空,field2不为空的情况。合并编辑确实如此。@Jonjilla我相信有人可以更好地回答这个问题……但是
NULL
只是一个不能比较的值。它实际上是没有值。它是比较存在的东西和不存在的东西。不是比较两个存在的东西。OP解释说,如果field1为NULL,那么一行也应该包括在内,而field2为NULL,如果两个字段都为NU,那么一行不应该包括在内LL.如果两个字段都为空,则此解决方案包括一行,但不包括字段1为空但字段2不为空的行。因此,这并不能解决OP的问题。@mathguy OP推断
field2
是唯一包含
NULL
的字段,因此它在
field1
。他还指出“如果字段1中的值不等于字段2中的值。”Orace使用三值逻辑-是否要包括或排除两个字段都为空的行?@mathguy排除当它们都为空时,因为它们实际上是等效的(我知道它们都为空,所以我们不能肯定,但这已经足够好了)这个解决方案是不正确的(考虑到OP对“不相等”的定义)。事实上,如果field1为NULL,但field2不为NULL,则不会包括该行;但是OP希望包括该行。
select * from my_table
where 
not case 
  when field1=field2 then 1
  when field1 is null and field2 is null then 1
  else 0
end = 1;