sql >> Base de Datos >  >> RDS >> Mysql

Comparar cadenas con una que tiene espacios vacíos antes mientras que la otra no

Los tipos CHAR llenan la cadena hasta la longitud del campo con bytes nulos (mientras que VARCHAR agrega delimitadores para indicar el final de la cadena, ignorando así los datos adicionales al final (Me refiero a bytes vacíos )) y, por lo tanto, las comparaciones que tengan espacios al final las ignorarán. Los espacios iniciales son relevantes ya que alteran la propia cadena. Ver la respuesta de Christopher.

EDITAR:se requiere más elaboración

Vea algunas pruebas prácticas a continuación. Los tipos VARCHAR agregan espacios a la cadena, mientras que los campos CHAR, aunque llenan la cadena hasta su tamaño con espacios, los ignoran durante las comparaciones. Ver específicamente la segunda línea con LENGTH consulta de función:

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)

donde MySQL establece que el campo CHAR, con el valor de 'a' tal como se insertó, tiene solo 1 carácter de longitud. Además, si concatenamos un poco de dato:

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)

puede ver que, dado que VARCHAR almacena donde termina la cadena, el espacio permanece en las concatenaciones, lo que no es cierto para los tipos CHAR. Ahora, teniendo en cuenta el anterior LENGTH ejemplo, donde la línea dos tiene longitudes diferentes para sus campos a y b, probamos:

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

Por lo tanto, podemos resumir afirmando que el tipo de datos CHAR ignora y recorta el espacio adicional al final de su cadena, mientras que VARCHAR no lo hace, excepto durante las comparaciones :

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)

Entonces, ¿es lo mismo cierto para el tipo 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)

Lo que muestra que los tipos CHAR y VARCHAR tienen diferentes métodos de almacenamiento, pero siguen las mismas reglas para la comparación de cadenas puras . Los espacios finales se ignoran; mientras que los espacios iniciales modifican la propia cadena.