SQL不在not equals查询上显示空值?

SQL不在not equals查询上显示空值?,sql,oracle,null,Sql,Oracle,Null,这只是一个出于好奇的问题,但我正在查看一个数据库并从一个表中提取数据,其中一列上有一个查询。该列有四个可能的值null、0、1、2。当我以以下方式运行查询时: SELECT * FROM STATUS WHERE STATE != '1' AND STATE != '2'; 我得到与跑步相同的结果: SELECT * FROM STATUS WHERE STATE = '0'; 也就是说,在查询列的top命令中有空值的行似乎从结果中被忽略了,这在SQL中总是发生吗 我正在通过Oracle S

这只是一个出于好奇的问题,但我正在查看一个数据库并从一个表中提取数据,其中一列上有一个查询。该列有四个可能的值null、0、1、2。当我以以下方式运行查询时:

SELECT * FROM STATUS WHERE STATE != '1' AND STATE != '2';
我得到与跑步相同的结果:

SELECT * FROM STATUS WHERE STATE = '0';

也就是说,在查询列的top命令中有空值的行似乎从结果中被忽略了,这在SQL中总是发生吗


我正在通过Oracle SQL Developer运行我的命令。

是的,这很正常,您可以将数据库设置用于修复该问题

但您可以修改代码并执行类似操作:

SELECT * FROM STATUS WHERE STATE != '1' OR STATE != '2' or STATE is null;
有关更多信息,请参阅:

在几种语言中,NULL的处理方式不同:大多数人都知道两值逻辑,其中true和false是布尔表达式中唯一可比较的值,即使false定义为0,true定义为其他值

在标准SQL中,您必须考虑。NULL不被视为实际值,您可以将其称为unknown。因此,如果该值未知,则不清楚在您的情况下,状态是0、1还是其他任何值。那么空!=1再次将结果设置为空

这就得出结论,无论在哪里过滤可能为NULL的内容,都必须自己处理NULL值。请注意,语法也不同:空值只能与x is NULL而不是x=NULL进行比较。有关显示逻辑运算结果的真值表,请参见Wikipedia。

带有where's的多个or可能很快变得难以阅读,结果也不确定

我建议在本例中使用额外的括号加上IN语句NOT IN,例如

从状态中选择*,其中状态不在“1”、“2”或状态为空

数据库供应商之间的实现可能有所不同,但上面的显式语法应该可以确保结果。

我创建了用于行为的脚本:


像这样使用NVL:从NVLSTATE的状态中选择*,'X'!='1'和NVLSTATE,'X'!='2';

我明白了,为快速回答干杯瓦什:我以后一定会记住这一点。我想在stackexchange,您通常会很快得到答案。如果你试着自己回答问题,你会发现很难找到一个你能回答并且你想回答的未回答的问题。然而,这也是一个简短的答案,现在我在家,我也将更新它,以反映三值逻辑。最好的答案是一英里,解决了真正的问题,这是三值逻辑。谢谢我是不是唯一一个认为这是设计任何类型的编程语言的根本错误的方法的人?这对我来说毫无意义。如果我说,'何处[价值]!=2' ... null不等于2!不管是谁决定使用这个“三值逻辑”——这似乎是一个错误的决定。@GregBlass我认为调用未知值NULL会导致主要的混乱。这不仅关系到是否可以比较相等的值,还关系到是否可以比较数据。在SQL中是否总是这样简短的回答是:没有。我说这是非常故意的,因为SQL的3VL规范不一致且不完整。你只需要学习所有的边缘案例。IMO最好的方法是避免SQL中出现空值。我知道这不会增加洞察,但OR应该是AND吗?从我记忆中的情况来看,当我这样做时,OR是正确的,即我只希望状态为0行,但我也得到空行。我不知道@Vash在回答中描述的三值逻辑。我应该使用STATE,而不是像michaeldurrant指出的那样在'1'和'2'中使用STATE。我的SQL比以前好多了,哈哈。记住这一点我觉得有点傻,但我突然想到@Pumbaa80是对的,我的意思是,或者说没有任何意义。国家不在。。。也是正确的。@onedaywhen极好的注释,特别是IMO最好的方法是避免由于SQL规范不一致而导致SQL中出现空值。这句话应该是一个答案,它将帮助很多人找到一个好的、干净的解决方案

create table field_values
(
is_user_deletable VARCHAR2(1 CHAR),
resource_mark VARCHAR2(3 CHAR)
)

insert into field_values values (NULL, NULL);
insert into field_values values ('Y', NULL);
insert into field_values values ('N', NULL);

select * from field_values; -- 3 row

-- 1 row, bad
update field_values set resource_mark = 'D' where is_user_deletable = 'Y'; 
update field_values set resource_mark = 'D' where is_user_deletable <> 'N'; 
update field_values set resource_mark = 'D' where is_user_deletable != 'N'; 
update field_values set resource_mark = 'D' where is_user_deletable not in ('Y');

-- 2 rows, good, but needs more SQL and more comparisons. Does DB optimizes?
update field_values set resource_mark = 'D' where is_user_deletable = 'N' or is_user_deletable is null; 

-- it better to have ('Y' and NULL) or ('N' and NULL), but not 'Y' and 'N' and NULL (avoid quires with https://en.wikipedia.org/wiki/Three-valued_logic)
-- adding new column which is 'Y' or 'N' only into existing table may be very long locking operation on existing table (or running long DML script)