Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Comparando strings com uma com espaços vazios antes, enquanto a outra não


Os tipos CHAR preenchem a string até o comprimento do campo com bytes nulos (enquanto VARCHAR adiciona delimitadores para indicar o final da string - ignorando assim dados extras no final (quero dizer bytes vazios )) e, portanto, as comparações com espaços no final as ignorarão. Espaços iniciais são relevantes, pois alteram a própria string. Veja a resposta de Christopher.

EDIT:algumas elaborações adicionais são necessárias

Veja alguns testes práticos abaixo. Os tipos VARCHAR adicionam espaços à string, enquanto os campos CHAR, embora preencham a string até seu tamanho com espaços, os ignoram durante as comparações. Veja especificamente a segunda linha com o LENGTH consulta de função:
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)

onde o MySQL informa que o campo CHAR, com o valor de 'a' conforme foi inserido, possui apenas 1 caractere de comprimento. Além disso, se concatenarmos alguns dados:
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)

você pode ver que, como VARCHAR armazena onde a string termina, o espaço permanece em concatenações - o que não é verdadeiro para tipos CHAR. Agora, tendo em mente o LENGTH anterior Por exemplo, onde a linha dois tem comprimentos diferentes para seus campos a e b, testamos:
mysql> SELECT * FROM test WHERE a=b;
+------+------+
| a    | b    |
+------+------+
| a    | a    | 
| a    | a    | 
|  a   |  a   | 
+------+------+
3 rows in set (0.00 sec)

Portanto, podemos resumir afirmando que o tipo de dados CHAR ignora e corta espaço extra no final de sua string, enquanto VARCHAR não - exceto durante comparações :
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)

Então, o mesmo vale para o 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)

O que mostra que os tipos CHAR e VARCHAR têm métodos de armazenamento diferentes, mas seguem as mesmas regras para comparação de string pura . Os espaços à direita são ignorados; enquanto os espaços iniciais modificam a própria string.