我有一个SQL查询
SELECT * FROM tableName WHERE colName != 'contents'
Run Code Online (Sandbox Code Playgroud)
现在与我的预期相反,这似乎与其内容为"NULL"的colName不匹配.看看SQLite如何处理NULL并且特别是这个条件"null OR true" is true对于SqlLite是正确的我认为我的查询足够用于选择带有NULLfor 的行colName.我必须错误地理解这一点.任何人都可以为我阐明这一点吗?我可以用
SELECT * FROM tableName WHERE (colName != 'contents' OR colName IS NULL)
Run Code Online (Sandbox Code Playgroud)
但我不认为我必须这样做.
谢谢
你可以通过使用IS NOT而不是使用来解决这个问题!=.如果您查看本文档的"运算符"部分,您将看到:
除非一个或两个操作数都为NULL,否则IS和IS NOT运算符的工作方式类似于=和!=.在这种情况下,如果两个操作数均为NULL,则IS运算符求值为1(true),IS NOT运算符求值为0(false).如果一个操作数为NULL而另一个操作数不为NULL,则IS运算符的计算结果为0(false),IS NOT运算符为1(true).IS或IS NOT表达式无法计算为NULL.运算符IS和IS的优先级与=不同.
我自己测试了这个:
sqlite> create table temp( dataColumn, nullColumn );
sqlite> insert into temp( dataColumn, nullColumn ) values ( 'test', NULL );
sqlite> select * from temp where nullColumn != 'test';
sqlite> select * from temp where nullColumn IS NOT 'test';
test|
sqlite> select * from temp where dataColumn IS NOT 'test';
sqlite>
Run Code Online (Sandbox Code Playgroud)
从更多的玩法来看,!=操作员似乎会评估NULL当你用它来比较某些东西时NULL:
sqlite> select ( 'contents' != NULL );
sqlite> select ( 'contents' == NULL );
sqlite> select ( 'contents' IS NULL );
0
sqlite> select ( 'contents' IS NOT NULL );
1
Run Code Online (Sandbox Code Playgroud)
大概这就是为什么你没有得到你期望的行为 - 你实际上是在说WHERE NULL != 'contents'什么评估为NULL,并且不满足WHERE子句