web-dev-qa-db-fra.com

Comment faire une recherche sensible à la casse dans la clause WHERE?

Je veux une recherche sensible à la casse dans la requête SQL. Mais par défaut, MySQL ne prend pas en compte le cas des chaînes.

Une idée sur la façon de faire une recherche sensible à la casse dans une requête SQL?

22
Somnath Muluk

par défaut, MySQL ne considère pas le cas des chaînes

Ce n'est pas tout à fait vrai. Quand tu create database dans MySQL, la base de données/le schéma a un jeu de caractères et un classement. Chaque jeu de caractères a un classement par défaut; voir ici pour plus d'informations.

Le classement par défaut pour le jeu de caractères latin1, lequel est latin1_swedish_ci, est insensible à la casse.

Vous pouvez choisir un classement sensible à la casse, par exemple latin1_general_cs ( grammaire MySQL ):

CREATE SCHEMA IF NOT EXISTS `myschema` 
DEFAULT CHARACTER SET latin1 
COLLATE latin1_general_cs ;

Cela a un effet sur des choses comme le regroupement et l'égalité. Par exemple,

create table casetable (
  id int primary key, 
  thing varchar(50)
);

select * from casetable;
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+

Dans une base de données sensible à la casse, nous obtenons:

select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| ABC   |        1 |
| aBc   |        1 |
| abC   |        1 |
| abc   |        1 |
+-------+----------+

select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
+----+-------+

Dans une base de données insensible à la casse, nous obtenons:

select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| abc   |        4 |
+-------+----------+

select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+

Notez que vous pouvez également modifier le classement à partir d'une requête . Par exemple, dans le cas - base de données sensible , je peux faire

select * from casetable where thing collate latin1_swedish_ci = "abc";
+----+-------+
| id | thing |
+----+-------+
|  3 | abc   |
|  4 | ABC   |
|  5 | aBc   |
|  6 | abC   |
+----+-------+
23
Matt Fenwick

Vous devez toujours indiquer avec votre question quelle version de MySQL vous utilisez, car MySQL est en développement constant.

Bon, revenons à votre question:

Les fonctions de chaîne dans MySQL sont toujours sensibles à la casse, vous pouvez donc utiliser n'importe laquelle des fonctions LOCATE, POSITION ou INSTR.

Par exemple:

SELECT phone FROM user WHERE POSITION('term' IN user_name)>0;

La correspondance de modèle avec une expression régulière (RLIKE ou REGEXP) est toujours sensible à la casse pour toutes les versions de MySQL à l'exception de la plus récente 3.23.4.

Par exemple:

SELECT phone FROM user WHERE user_name REGEXP 'term';

Pour la comparaison normale (=) et la correspondance de modèle SQL (LIKE), le comportement dépend des champs impliqués:

une. CHAR, VARCHAR et toutes les variantes des champs TEXT ne comparent pas la casse.

b. CHAR BINARY, VARCHAR BINARY et toutes les variantes des champs BLOB se comparent à la casse.

Si vous comparez un champ de (a) avec un champ de (b), la comparaison sera sensible à la casse (la sensibilité à la casse l'emporte). Voir le chapitre "7.2.7 Types de chaînes" du Manuel de référence MySQL et recherchez les instructions sur le tri et les comparaisons.

À partir de la version 3.23.0, il est également possible de forcer une comparaison en respectant la casse avec l'opérateur de conversion BINARY, indépendamment des types de champs impliqués. Voir le chapitre "7.3.7 Opérateurs Cast" du Manuel de référence MySQL.

Vous pouvez donc également changer le type de nom_utilisateur, ou avec V3.23.x, essayez quelque chose comme:

SELECT phone FROM user WHERE BINARY username LIKE '%term%';
15
Turgut

Dans ma situation , j'utilise Access 2010, mais j'ai eu le même problème mais la solution est différente: utilisez la fonction StrComp() fonction et tester son retour à zéro.

StrComp( thing, 'abc', 0) = 0

Parce que StrComp() renvoie -1 Si le premier argument est "plus petit", 1 S'il est "plus grand" et 0 S'il est "égal" , lorsque StrComp()=0, vous avez une correspondance sensible à la casse.

Voir ici , ici ou ici .

1
Martin F

Cela fonctionnera dans MySQL quel que soit le jeu de caractères.

SELECT 'test' REGEXP BINARY 'TEST' AS RESULT;

En mettant 'BINARY' force une comparaison binaire.

1
user2288580