为什么 Postresql 中 SQL 字符串相等和 LIKE 运算符的结果不同?[关闭]

Why the result is different for SQL string equality and for LIKE operator in Postresql? [closed]

提问人:Jónás Balázs 提问时间:10/24/2023 最后编辑:Jónás Balázs 更新时间:10/24/2023 访问量:60

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

29天前关闭。

我有一个带有登录名的表。登录名不包含任何特殊字符,并且类型为 varchar(50)。[a-zA-Z0-9]

我想通过登录名查找用户,例如:

CREATE TABLE users( login character varying(50) );
INSERT INTO users VALUES ('user1');
INSERT INTO users VALUES ('user2');

SELECT *
FROM users
WHERE ...;

和有什么不一样login LIKE 'exactMatch'login LIKE 'exactMatch%'login = 'exactMatch'

我希望对于这个两行数据库,以下条件都返回相同的结果:

login LIKE '%user1'
login LIKE 'user1%'
login = 'user1'
login LIKE 'user1'

在某些情况下,对于更复杂的登录名,最后两个条件会失败。

PostgreSQL Where-Clause 类 SQL

评论

0赞 Nico Haase 10/24/2023
“工作”或“不工作”是什么意思?另外,除了 true 之外,select 子句中还应该返回什么?login='user1'
0赞 Dmitry Bychenko 10/24/2023
login LIKE 'exactMatch%'表示“从”开始:后跟零个或多个任意符号。请注意,这是一个通配符,其中 - 任意符号和 - 零个或多个任意符号exactMatchexactMatchLike_%
0赞 Leonard 10/24/2023
您应该尝试在 dbfiddle 中重现该问题。
1赞 Leonard 10/24/2023
@JónásBalázs 如果它适用于某些数据,那么问题可能不在于查询,而在于数据。您确定某些用户名中没有任何其他特殊字符或空格吗?这是一个很长的镜头,但是,在这种情况下,如果您尝试 trim(login) = 'username' 而不是 login = 'username',这会给你带来预期的结果吗?
1赞 jjanes 10/24/2023
您的示例需要演示问题。相反,你的证明了问题的不存在。

答:

1赞 Cargo23 10/24/2023 #1

首先,让我们回答你提出的问题:

login LIKE 'exactMatch'、login LIKE 'exactMatch%' 和 login = 'exactMatch' 有什么区别

login LIKE 'exactMatch'和 'login = 'exactMatch'' 是等效的。

当你把一个或放到字符串中时,你就进入了 的模式匹配功能。当您拥有 时,您将获得以“exactMatch”开头的登录名,后跟任意数量的字符。%_LIKElogin LIKE 'exactMatch%'

现在,我认为您在最后描述的问题是,您发现您必须在 LIKE 子句中使用才能获得您期望的匹配项。我猜这是由于您的登录名中实际上存在意外字符,或者可能是字符集的问题。%

您可能会通过运行查询来查找不可打印的字符并从登录名中去除空格来发现问题:

SELECT login FROM users
WHERE login <> trim(regexp_replace(login, '[^[:print:]]', 'x', 'g'));
1赞 Maimoona Abid 10/24/2023 #2

在处理字符串以匹配模式时,可以在 SQL 中使用多个运算符和通配符。 以下是您在问题中提到的三个条件之间的主要区别。

login LIKE 'exactMatch' 和 login = 'exactMatch'登录列与“exactMatch”完全匹配的行将同时满足这两个条件。这两者都需要对“exactMatch”进行精确且区分大小写的匹配。

登录 LIKE 'exactMatch%'此条件将匹配登录列以“exactMatch”开头的行。通配符 % 匹配“exactMatch”之后的任何字符串。

问题的第二个查询的结果是结果集,而不是布尔值。结果将是一个行列表,每行都有一个列,该列具有布尔值,指示该行的登录列是否以“user1”开头。虽然这是 SELECT 语句的不常见应用,但 SQL 查询是有效的。

如果要计算满足此条件的行数,可以使用 COUNT 函数,它将为您提供登录列以“user1”开头的行数。

SELECT COUNT(*)
FROM users
WHERE login LIKE 'user1%';