postgresql NOT ILIKE子句不包含空字符串值

app*_*pie 17 sql postgresql

这是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.

  • “年轻人,数学你不懂,你习惯就好了。” ——约翰·冯·诺依曼 (3认同)
  • 我喜欢你对 *unknowns* 的解释,但我不确定它是如何连接 SQL 的。为什么 `WHERE null ILIKE '%anything%'` 是未知的? (2认同)
  • 哦,萨斯.这是一个难以跟进的问题吗? (2认同)
  • @applepie:与冯·诺伊曼不同意可能看起来很自大,但这实际上很容易理解IMO.想象一个黑盒子.你不知道它里面有什么.内容是*未知*.如果你问内容是否像'%anything%`,你无法确定.答案是*未知*以及...... (2认同)

jde*_*lop 6

您可以使用COALESCE来实现您的目标,例如

SELECT * FROM table WHERE COALESCE(some_text,'') NOT ILIKE "%anything%';
Run Code Online (Sandbox Code Playgroud)