这是Postgresql 9.2.4的设置:
CREATE TABLE table (
id integer NOT NULL,
some_text text
);
Run Code Online (Sandbox Code Playgroud)
现在我们输入一个记录,其中包含null或空字符串some_text,以便在我们查询时:
SELECT * FROM table WHERE some_text IS NULL;
Run Code Online (Sandbox Code Playgroud)
我得到了回来.到现在为止还挺好.
但是,当我查询时:
SELECT * FROM table WHERE some_text NOT ILIKE "%anything%';
Run Code Online (Sandbox Code Playgroud)
我发现没有任何回复.这是为什么?我希望null或空字符串"不喜欢anything".
Bil*_*win 45
在SQL中,NULL不等于任何东西.它也不是不平等的.
换句话说,如果我不告诉你我的中间名,而你没有告诉我你的中间名,我们怎么知道我们的两个中间名是相同的名字还是不同的名字?我们无法知道.
这通常会使人们在SQL中绊倒,因为它是"三值逻辑".表达式可以是TRUE,FALSE或UNKNOWN.我们这些熟悉布尔代数的人都知道NOT TRUE是FALSE,而NOT FALSE是TRUE.
但棘手的部分是NOT UNKNOWN仍然未知.
因此,您的解决方案是始终在列中存储非空字符串,或者使用表达式来计算三值逻辑:
SELECT * FROM table WHERE some_text NOT ILIKE "%anything%' OR some_text IS NULL;
Run Code Online (Sandbox Code Playgroud)
要么:
SELECT * FROM table WHERE COALESCE(some_text, '') NOT ILIKE '%anything%';
Run Code Online (Sandbox Code Playgroud)
PostgreSQL还支持null安全等于运算符:
SELECT * FROM table WHERE some_text IS DISTINCT FROM 'anything';
Run Code Online (Sandbox Code Playgroud)
但遗憾的是,这仅适用于平等,而不适用于具有模式和通配符的LIKE/ILIKE.
您可以使用COALESCE来实现您的目标,例如
SELECT * FROM table WHERE COALESCE(some_text,'') NOT ILIKE "%anything%';
Run Code Online (Sandbox Code Playgroud)