最近,我们在生成SQLite查询时遇到了一个问题,我们意外地使用了按位OR:
SELECT * FROM demo WHERE ((nullableId IS NULL) | (nullableId = -1))
我们使用
OR
运算符解决了此问题。但是上面的查询有一些我不理解的意外行为:
为什么这甚至有效? (例如,在Microsoft SQL Server中,这显然是语法错误)
为什么结果所有带有
nullableId = -1
的行?简而言之,这是怎么回事?
最佳答案
当nullableId IS NULL
时,条件评估:nullableId IS NULL
至1nullableId = -1
到NULL
(因为与NULL
的任何比较都会返回NULL
)
所以这个表达式:
(nullableId IS NULL) | (nullableId = -1)
计算为
NULL
,并且由于t不是TRUE
,因此不返回这些行。但是,当
nullableId = -1
时,表达式的计算结果为:0 | 1 = 1
因此,返回所有带有
nullableId = -1
的行。您可以在如下表中看到此行为:
create table demo(nullableId int);
insert into demo(nullableId) values
(1), (null), (-1), (2);
查询:
SELECT *,
(nullableId IS NULL),
(nullableId = -1),
(nullableId IS NULL) | (nullableId = -1)
FROM demo
返回:
| nullableId | (nullableId IS NULL) | (nullableId = -1) | (nullableId IS NULL) | (nullableId = -1) |
| ---------- | -------------------- | ----------------- | ---------------------------------------- |
| 1 | 0 | 0 | 0 |
| null | 1 | null | null |
| -1 | 0 | 1 | 1 |
| 2 | 0 | 0 | 0 |