Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comparer des chaînes avec l'une ayant des espaces vides avant tandis que l'autre n'en a pas

Les types CHAR remplissent la chaîne jusqu'à la longueur du champ avec des octets nuls (alors que VARCHAR ajoute des délimiteurs pour indiquer la fin de la chaîne - ignorant ainsi les données supplémentaires à la fin (je veux dire des octets vides )), et donc les comparaisons qui ont des espaces à la fin les ignoreront. Les espaces de début sont pertinents car ils modifient la chaîne elle-même. Voir la réponse de Christopher.

EDIT :quelques précisions supplémentaires sont nécessaires

Voir quelques tests pratiques ci-dessous. Les types VARCHAR ajoutent des espaces à la chaîne, tandis que les champs CHAR, même s'ils remplissent la chaîne jusqu'à sa taille avec des espaces, les ignorent lors des comparaisons. Voir spécifiquement la deuxième ligne avec le LENGTH requête de fonction :

mysql> create table test (a VARCHAR(10), b CHAR(10));
Query OK, 0 rows affected (0.17 sec)

mysql> insert into test values ('a', 'a'), ('a ', 'a '), (' a', ' a');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select a, LENGTH(a), b, LENGTH(b) FROM test;
+------+-----------+------+-----------+
| a    | LENGTH(a) | b    | LENGTH(b) |
+------+-----------+------+-----------+
| a    |         1 | a    |         1 | 
| a    |         2 | a    |         1 | 
|  a   |         2 |  a   |         2 | 
+------+-----------+------+-----------+
3 rows in set (0.00 sec)

où MySQL indique que le champ CHAR, avec la valeur de 'a' tel qu'il a été inséré, n'a qu'un seul caractère de long. De plus, si on concatène un peu de données :

mysql> select CONCAT(a, '.'), CONCAT(b, '.') FROM test;
+----------------+----------------+
| CONCAT(a, '.') | CONCAT(b, '.') |
+----------------+----------------+
| a.             | a.             | 
| a .            | a.             | 
|  a.            |  a.            | 
+----------------+----------------+
3 rows in set (0.00 sec)

mysql> select CONCAT(a, b), CONCAT(b, a) FROM test;
+--------------+--------------+
| CONCAT(a, b) | CONCAT(b, a) |
+--------------+--------------+
| aa           | aa           | 
| a a          | aa           | 
|  a a         |  a a         | 
+--------------+--------------+
3 rows in set (0.00 sec)

vous pouvez voir que, puisque VARCHAR stocke où la chaîne se termine, l'espace reste sur les concaténations - ce qui n'est pas vrai pour les types CHAR. Maintenant, en gardant à l'esprit le précédent LENGTH exemple, où la ligne deux a des longueurs différentes pour ses champs a et b, nous testons :

mysql> SELECT * FROM test WHERE a=b;
+------+------+
| a    | b    |
+------+------+
| a    | a    | 
| a    | a    | 
|  a   |  a   | 
+------+------+
3 rows in set (0.00 sec)

Par conséquent, nous pouvons résumer en indiquant que le type de données CHAR ignore et supprime l'espace supplémentaire à la fin de sa chaîne, tandis que VARCHAR ne le fait pas - sauf lors des comparaisons :

mysql> select a from test where a = 'a ';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where a = 'a';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where a = ' a';
+------+
| a    |
+------+
|  a   | 
+------+
1 row in set (0.00 sec)

Alors, est-ce la même chose pour le type CHAR ?

mysql> select a from test where b = 'a ';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where b = 'a';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where b = ' a';
+------+
| a    |
+------+
|  a   | 
+------+
1 row in set (0.00 sec)

Ce qui montre que les types CHAR et VARCHAR ont des méthodes de stockage différentes, mais suivent les mêmes règles pour la comparaison pure des chaînes . Les espaces de fin sont ignorés ; tandis que les espaces de début modifient la chaîne elle-même.