16 votes

Comment filtrer une colonne avec des caractères non accentués à l'aide d'une requête de sélection ?

J'ai une table MySQL (test) avec un encodage charset utf-8. Il y a trois entrées, deux entrées avec des caractères normaux et un autre nom avec des caractères accentués.

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, 'áááá');

Si j'exécute la requête de sélection suivante, elle renvoie les 3 entrées.

Résultat réel:-

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

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

Au lieu de cela, ce devrait être le retour de la dernière entrée avec id=3.

Je ne veux pas utiliser 'BINARY' ou 'COLLATE utf8_bin' parce que cela renvoie uniquement une recherche sensible à la casse.

J'ai besoin d'une recherche normale avec une chaîne de caractères comme requête, par exemple : -

Résultat attendu : -

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

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

6voto

user3802077 Points 785

La collation utf8_bin est celle dont vous avez besoin pour gérer les accents.

Je ne veux pas utiliser 'BINARY' ou 'COLLATE utf8_bin' parce que cela renvoie uniquement une recherche sensible à la casse.

Il est plus facile (et plus performant) de résoudre ce problème avec utf8_bin que de résoudre le problème de l'accent avec une autre collation.

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

-> ajouté après les commentaires

La requête ci-dessus suppose que les paramètres de la requête sont minuscules mais si vous ne pouvez pas modifier les paramètres pour qu'ils soient toujours minuscules, vous pouvez aussi utiliser cette variante

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

4voto

Károly Nagy Points 1475

utf8_bin est la collation que vous souhaitez pour distinguer les caractères accentués.

Dans la requête, vous pouvez utiliser lower pour rendre la requête insensible à la casse.

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)

1voto

Fathah Rehman P Points 2509

Vous pouvez résoudre votre problème en utilisant la requête suivante

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

convert est utilisé pour convertir les jeux de caractères

1voto

iLikeMySql Points 596

L'utilisation de RLIKE (REGEXP) pourrait résoudre votre problème (il retournera le résultat attendu en utilisant une version plus puissante de like).

de MYSQL-Documentation :
Une expression régulière est un moyen puissant de spécifier un modèle pour une recherche complexe.
.... REGEXP n'est pas sensible à la casse, sauf lorsqu'il est utilisé avec des chaînes binaires.

remplacez simplement

where name like '%aa%'

avec

where Name rlike 'aa';

pour effectuer une recherche insensible à la casse de l'expression "aa".

MAIS :
Cette approche peut s'avérer peu sûre, car des résultats inattendus peuvent être produits en comparant des caractères à plusieurs octets, selon la documentation MySQL.

1voto

corretge Points 680

Vous pouvez essayer avec :

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

Mais attention, convert a des problèmes de performance sur les index. Plus d'informations sur http://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X