Как фильтровать столбец с неадресными символами с помощью запроса выбора

У меня есть таблица MySQL (test) с кодировкой кодировки utf-8. Есть три записи, две записи с нормальными символами и другое имя с символами акцента.

CREATE TABLE test (
  id Integer,
  name VARCHAR(50), 
  PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO `test` (`id`, `name`) VALUES (1, 'aaaa');
INSERT INTO `test` (`id`, `name`) VALUES (2, 'AAAA');
INSERT INTO `test` (`id`, `name`) VALUES (3, 'áááá');

Если я запустил следующий запрос select, он вернет все 3 записи

Фактический результат: -

select * from test where name like '%aa%';

id  | name
----|----
1   | aaaa
2   | AAAA
3   | áááá

Вместо этого должна быть возвращена последняя запись с id = 3.

Я не хочу использовать "BINARY" или "COLLATE utf8_bin", потому что он возвращает только поиск с учетом регистра.

Мне нужен нормальный поиск с запросом строки как, например: -

Ожидаемый результат: -

select * from test where name like '%aa%';

id | name
---|-----
1  | aaaa
2  | AAAA

Ответы

Ответ 1

Сравнение utf8_bin - это то, что вам нужно для вашего требования для обработки акцентов

Я не хочу использовать "BINARY" или "COLLATE utf8_bin", потому что он возвращает только поиск с учетом регистра.

Это проще (и более результативно) решать с помощью utf8_bin, чем решать проблему акцента с другой сортировкой

SELECT * FROM test WHERE LOWER(name) like '%aa%' COLLATE utf8_bin

- > добавлено после комментариев

В приведенном выше запросе предполагается, что параметры запроса являются незначительными, но если вы не можете изменить параметры, всегда быть minuscules, вы также можете использовать это изменение

SELECT * FROM test WHERE LOWER(name) like LOWER('%ÚÙ%') COLLATE utf8_bin

Ответ 2

utf8_bin - это сортировка, которую вы хотите отличить акцентированные символы.

В запросе пользователь lower может сделать запрос нечувствительным к регистру.

CREATE TABLE `token` (
  `id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

mysql> select * from token where lower(name) like '%aa%';
+----+------+
| id | name |
+----+------+
|  1 | aaaa |
|  2 | AAAA |
+----+------+
2 rows in set (0.00 sec)

Ответ 3

Вы можете решить свою проблему, используя следующий запрос

  select * from token where (convert(name using ASCII)) like '%aa%'

convert используется для преобразования между наборами символов

Ответ 4

Использование RLIKE (REGEXP) может решить вашу проблему (он вернет ваш ожидаемый результат, используя более мощную версию)

из документации MYSQL:
     Регулярное выражение является мощным способом задания шаблона для сложного поиска.
.... REGEXP не чувствителен к регистру, кроме случаев, когда используется с двоичными строками.

просто замените

where name like '%aa%'

с

where Name rlike 'aa';

сделать нечувствительный к регистру поиск выражения 'aa'.

НО:
Это может быть как-то небезопасным, поскольку неожиданные результаты могут быть получены путем сравнения многобайтовых символов в соответствии с MySQL Documentation.

Ответ 5

Вы можете попробовать:

SELECT * FROM test.test
where convert(name using ascii) like '%aa%';

Но будьте осторожны, конвертер имеет проблемы с производительностью в индексах. Дополнительная информация на http://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html