在关于 stackoverflow 的另一篇文章中,我读到 INSTR 可用于按相关性对结果进行排序。

我对 col LIKE '%str%' and INSTR(col, 'str')` 的理解是它们的行为相同。排序规则的处理方式似乎有所不同。

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO users (name)
VALUES ('Joël'), ('René');

SELECT * FROM users WHERE name LIKE '%joel%'; -- 1 record returned
SELECT * FROM users WHERE name LIKE '%rene%'; -- 1 record returned
SELECT * FROM users WHERE INSTR(name, 'joel') > 0; -- 0 records returned
SELECT * FROM users WHERE INSTR(name, 'rene') > 0; -- 0 records returned
SELECT * FROM users WHERE INSTR(name, 'joël') > 0; -- 1 record returned
SELECT * FROM users WHERE INSTR(name, 'rené') > 0; -- 1 record returned

虽然 INSTR 做了一些转换,但它会在 ë 中找到 é
SELECT INSTR('é', 'ë'), INSTR('é', 'e'), INSTR('e', 'ë');
-- returns 1, 0, 0

我错过了什么吗?

http://sqlfiddle.com/#!2/9bf21/6(使用 mysql 版本:5.5.22)

最佳答案

这是由于 bug 70767 on LOCATE() and INSTR() 已验证。

尽管 INSTR() 文档指出它可以用于多字节字符串,但正如您所注意到的,它似乎不起作用,使用 utf8_general_ci 之类的排序规则,其中 should be case and accent insensitive



错误报告指出,尽管 MySQL 正确执行此操作,但只有在字节数也相同时才会执行此操作:



为了歪曲报告示例,如果您创建下表:

create table t ( needle varchar(10), haystack varchar(10)
                  ) COLLATE=utf8_general_ci;
insert into t values ("A", "a"), ("A", "XaX");
insert into t values ("A", "á"), ("A", "XáX");
insert into t values ("Á", "a"), ("Á", "XaX");
insert into t values ("Å", "á"), ("Å", "XáX");

然后运行此查询,您可以看到相同的行为:
select needle
     , haystack
     , needle=haystack as `=`
     , haystack LIKE CONCAT('%',needle,'%') as `like`
     , instr(needle, haystack) as `instr`
  from t;

SQL Fiddle

关于mysql - 当 str 包含 'é' 或 'ë' 且 substr 仅包含 'e' 时,INSTR(str,substr) 不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20923186/

10-11 08:32