SQLite中NOT运算符行为不一致问题求助
问题根源:SQL运算符的优先级与结合性
这个矛盾的核心是你忽略了SQL中运算符的优先级和结合规则,尤其是IS NOT和=这两个比较运算符的处理顺序。我来一步步拆解你的例子:
1. 错误的条件解析逻辑
你写的第三个查询:
SELECT * FROM demo WHERE Name="SQL " || "Online" AND Hint=1 IS NOT 1
你可能默认这个条件会被解析成:
Name="SQL Online" AND (Hint = (1 IS NOT 1))
也就是等价于Name="SQL Online" AND Hint=0——但这是错的!
在SQLite中,IS NOT和=属于同一优先级的比较运算符,并且遵循左结合的规则(也就是从左到右依次计算)。所以实际的解析逻辑是:
Name="SQL Online" AND ((Hint=1) IS NOT 1)
翻译成人话就是:先判断Hint是否等于1,得到一个布尔结果(1为真,0为假);再判断这个结果是不是不等于1——也就是判断「Hint等于1」这件事是否为假。
2. 为什么查询会返回结果?
如果你的目标记录的Hint值不是1(比如是2、3或者其他值),那么:
Hint=1会返回0(假)0 IS NOT 1会返回1(真)- 整个WHERE条件就变成
Name="SQL Online" AND 1,也就是逻辑真,自然会返回这条记录。
而你显式执行... AND Hint=0时没有结果,恰恰说明这条记录的Hint值不是0,而是其他非1的值——这就是两种写法结果不同的原因,它们根本不是等价的条件!
3. 验证与解决方法
你可以执行这条SQL来直观看到差异:
SELECT *, (Hint=1) IS NOT 1 AS actual_condition, Hint=0 AS your_expected_condition FROM demo WHERE Name="SQL " || "Online"
你会发现actual_condition是1(真),而your_expected_condition是0(假),这就清晰展示了两种条件的区别。
如果你的真实需求是让Hint等于1 IS NOT 1的结果(也就是0),只需要用括号明确优先级即可:
SELECT * FROM demo WHERE Name="SQL " || "Online" AND Hint=(1 IS NOT 1)
这样SQLite就会先计算括号内的1 IS NOT 1得到0,再和Hint比较,结果就和你预期的一致了。
内容的提问来源于stack exchange,提问作者0Interest
相关产品推荐
相关产品推荐

