查询Teradata时,我被NOT LIKE ANY
关键字抓住了。
通过用简单的英语解析关键字,我希望查询返回任何与参数列表中的值不同的值。
但是,由于语句生成的布尔逻辑(即NOT LIKE X OR NOT LIKE Y
),返回表中的所有值。 我实际需要的关键字是NOT LIKE ALL
(即NOT LIKE X AND NOT LIKE Y
)。
使用 Postgresql 的示例:
CREATE TABLE t
("col" varchar(7))
;
INSERT INTO t
("col")
VALUES
('Andrew'),
('Annie'),
('Bob'),
('Bowie'),
('Charles')
;
/* Returns 'Charles' */
select col
from t
where col not like all (array[ 'An%', 'Bo%' ])
;
/* Returns all values in table */
select col
from t
where col not like any (array[ 'An%', 'Bo%' ])
;
我理解为什么返回这些结果背后的基本逻辑,但我的问题是是否有任何使用NOT LIKE ANY
有意义的情况?
如果不是,数据库引擎是否有充分的理由支持此关键字,因为基于关键字的简单英语解释可能存在歧义?
是的,它确实有意义,只是略有修改。
以这个查询为例:
SELECT g
FROM generate_series(9995, 10005) g
WHERE g::TEXT NOT LIKE ANY(ARRAY['9996','9997'])
如果g
NOT LIKE
其中任何一个,则返回 TRUE。感兴趣的项目是编号 9996 和 9997。9996 与数组中第一项的NOT LIKE
比较计算结果为 FALSE,因为 9996 不是 9996NOT LIKE
。但是我们正在寻找任何比赛,所以我们继续下一场比赛。9996 不像 9997,因此评估为 TRUE,并且包含 9996。比较 9997 时相同,但第一次比较返回 TRUE。因此,将选择generate_series中的所有数字。
现在稍微改变一下:
SELECT g
FROM generate_series(9995, 10005) g
WHERE NOT g::TEXT LIKE ANY(ARRAY['9996','9997'])
因为一旦比较返回 TRUE,对 ANY 的评估就会停止(我试图为此找到官方来源,但不能,但是我之前读过它并且很确定它是有道理的),当使用LIKE
将 9996 与 9996 进行比较时,ANY
搜索中止,因为找到了匹配项。然后被NOT
否定,因此 9996 被排除在结果之外。
9997 也有类似的故事,除了第一次比较不是 TRUE,所以它继续到下一个比较,即 TRUE 然后否定成为 FALSE。其余数字不匹配,因此 ANY 返回 FALSE,将其否定为 TRUE。
如果此查询的结果是除 9996 和 9997 之外的所有数字generate_series。
顺便说一下,如果数组只有一个值,那么g::TEXT NOT LIKE ANY([your array])
将返回预期的结果。
如果您使用的是ANY
而不是ALL
,则不会排除任何行。在这里,ANY
会表现得像OR
.因此,在您想要将OR
用于IN
的任何情况下,都可以使用ANY
.
最好不要使用ANY
,因为我们等于不等于不 equal.ie 它与IN