web-dev-qa-db-fra.com

Comme Case Sensitive dans MySQL

J'ai une requête MySQL:

SELECT concat_ws(title,description) as concatenated HAVING concatenated LIKE '%SearchTerm%';

Et ma table est encodée avec utf8_general_ci avec MyISAM.

Les recherches semblent être sensibles à la casse.

Je n'arrive pas à comprendre comment résoudre ce problème. Qu'est-ce qui ne va pas et/ou comment puis-je résoudre le problème?

30
Pmc Machinery

Essaye ça:

SELECT LOWER(CONCAT_WS(title,description)) AS concatenated 
WHERE concatenated LIKE '%searchterm%'

ou (pour vous laisser voir la différence)

SELECT LOWER(CONCAT_WS(title,description)) AS concatenated 
WHERE concatenated LIKE LOWER('%SearchTerm%')
18
Marco

Une solution bien meilleure en termes de performances:

SELECT .... FROM .... WHERE `concatenated` LIKE BINARY '%SearchTerm%';

La comparaison de chaînes est sensible à la casse lorsque l'un des opérandes est une chaîne binaire.

Une autre alternative consiste à utiliser COLLATE,

SELECT ....
FROM ....
WHERE `concatenated` like '%SearchTerm%' COLLATE utf8_bin;
39
kolypto

Dans cette méthode, il n'est pas nécessaire de sélectionner le champ recherché:

SELECT table.id 
FROM table
WHERE LOWER(table.aTextField) LIKE LOWER('%SearchAnything%')
5
Malkocoglu

Cela fonctionne aussi:

SELECT LOWER(DisplayName) as DN
FROM   Bidders
WHERE  OrgID=45
HAVING DN like "cbbautos%"
LIMIT  10;
0
david

Vérifiez CHARSET mentionné dans le schéma de la table:

show create table xyz;

Basé sur CHARSET, vous pouvez essayer les solutions suivantes.

select name from xyz where name like '%Man%' COLLATE latin1_bin;
select name from xyz where name like '%Man%' COLLATE utf8_bin;

Voici les cas qui ont fonctionné pour moi, CHARSET = latin1, version de MySQL = 5.6.

mysql> select installsrc from appuser where installsrc IS NOT NULL and installsrc like 'Promo%' collate latin1_bin limit 1;
+-----------------------+
| installsrc            |
+-----------------------+
| PromoBalance_SMS,null |
+-----------------------+
1 row in set (0.01 sec)

mysql>
mysql> select installsrc from appuser where installsrc IS NOT NULL and installsrc like 'PROMO%' collate latin1_bin limit 1;
+---------------------------+
| installsrc                |
+---------------------------+
| PROMO_SMS_MISSEDCALL,null |
+---------------------------+
1 row in set (0.00 sec)

mysql> select installsrc from appuser where installsrc IS NOT NULL and installsrc like 'PROMO%' limit 1;
+-----------------------+
| installsrc            |
+-----------------------+
| PromoBalance_SMS,null |
+-----------------------+
1 row in set (0.01 sec)
0
minhas23

Juste pour compléter, au cas où cela aiderait: 

Comme indiqué sur https://dev.mysql.com/doc/refman/5.7/fr/case-sensitivity.html , pour les jeux de caractères par défaut, les comparaisons de chaînes non binaires ne tiennent pas compte de la casse.

Par conséquent, un moyen facile d'effectuer des comparaisons sans distinction de casse est de convertir le champ en type CHAR, VARCHAR ou TEXT.

Voici un exemple avec une vérification sur un seul champ:

SELECT * FROM table1 WHERE CAST(`field1` AS CHAR) LIKE '%needle%';
0
Cédric Françoys