SQL不在非等于查询上显示空值?

时间:2011-11-07 12:44:40

标签: sql oracle null

这只是一个好奇的问题,但我正在查看一个数据库并从一个表中提取数据,并在其中一个列上查询。该列有四个可能的值null012。当我将查询运行为:

SELECT * FROM STATUS WHERE STATE != '1' AND STATE != '2';

我得到的结果与跑步相同:

SELECT * FROM STATUS WHERE STATE = '0';

即。查询列中top命令中具有空值的行似乎从结果中省略,这是否总是发生在SQL中?

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

5 个答案:

答案 0 :(得分:29)

在几种语言中,NULL的处理方式不同:大多数人都知道二值逻辑,其中truefalse是布尔表达式中唯一可比较的值(即使是假定义为0,也是真的其他任何事情)。

在标准SQL中,您必须考虑three-valued logic。 NULL不被视为实际值,您可以将其称为“未知”。因此,如果值未知,则不清楚在您的情况下state是0,1还是其他任何内容。因此NULL != 1再次向NULL结果。

这样就得出结论,无论您过滤掉可能为NULL的内容,都必须自己处理NULL值。请注意,语法也不同:NULL值只能与x IS NULL而不是x = NULL进行比较。请参阅Wikipedia,了解显示逻辑运算结果的真值表。

答案 1 :(得分:9)

是的,这是正常的,你可以设置一个数据库设置来修复

但你可以修改你的代码并做类似的事情:

SELECT * FROM STATUS WHERE STATE != '1' OR STATE != '2' or STATE is null;

请查看此信息以获取更多信息: http://www.w3schools.com/sql/sql_null_values.asp

答案 2 :(得分:5)

带有or的多个where很快就会变得难以阅读并且不确定结果。

我建议使用额外的括号加上使用IN语句(在这种情况下为NOT IN),例如

SELECT * FROM STATUS WHERE (STATE NOT IN ('1', '2')) or STATE is null;

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

答案 3 :(得分:2)

像这样使用NVLSELECT * FROM STATUS WHERE NVL(STATE,'X') != '1' AND NVL(STATE,'X')!= '2';

答案 4 :(得分:0)

我为research Oracle行为创建了脚本:

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)