在另一篇关于堆栈溢出的文章中,我看到INSTR可以用来根据相关性排序结果。
我对col LIKE '%str%' andINSTR的理解是,它们的行为是相同的。排序规则的处理方式似乎有所不同。
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)
发布于 2014-01-04 17:00:03
这是由于INSTR(),这已经得到了验证。
虽然INSTR()文档声明它可以用于多字节字符串,但是,正如您注意到的那样,它似乎不适用于像utf8_general_ci这样的排序规则( 应该是大小写和口音不敏感 )。
此函数是多字节安全的,并且只有在至少一个参数是二进制字符串时才区分大小写。
bug报告指出,虽然MySQL正确地做到了这一点,但只有在字节数相同的情况下才这样做:
但是,您可以很容易地观察到,当在另一个字符串中查找一个字符串时,它们(完全)不尊重排序规则。看起来,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;https://stackoverflow.com/questions/20923186
复制相似问题