Comparing strings with one having empty spaces before while the other does not

前端 未结 2 1857
清歌不尽
清歌不尽 2020-12-10 18:48

If I have to find a string name \"Akito\" and it lies in the table foo then following is the normal procedure,

select * from foo where `name = \         


        
相关标签:
2条回答
  • 2020-12-10 19:11

    http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html says the following:

    In particular, trailing spaces are significant, which is not true for CHAR or VARCHAR comparisons performed with the = operator:

    mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
    +------------+---------------+
    | 'a' = 'a ' | 'a' LIKE 'a ' |
    +------------+---------------+
    |          1 |             0 |
    +------------+---------------+
    1 row in set (0.00 sec)
    

    Trailing means not leading. Those seem to be relevant.

    0 讨论(0)
  • 2020-12-10 19:23

    CHAR types fill the string to the length of the field with null bytes (while VARCHAR add delimiters to indicate the end of the string - thus ignoring extra data at the end (I mean empty bytes)), and therefore comparisons that have spaces at the end will ignore those. Leading spaces are relevant as their alter the string itself. See Christopher's answer.

    EDIT: some further elaboration required

    See some practical tests below. VARCHAR types do add spaces to the string, whilst CHAR fields, even though they fill the string up to its size with spaces, ignore them during comparisons. See specifically the second line with the LENGTH function query:

    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)
    

    where MySQL states the CHAR field, with the value of 'a ' as it was inserted, has only 1 character in length. Furthermore, if we concatenate a little data:

    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)
    

    you can see that, since VARCHAR does store where the string ends, the space remains on concatenations - which does not hold true for CHAR types. Now, keeping in mind the previous LENGTH example, where line two has different lengths for its fields a and b, we test:

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

    Therefore, we can sum up stating that the CHAR datatype ignores and trims extra space at the end of its string, while VARCHAR does not - except during comparisons:

    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)
    

    So, is the same true for the CHAR type?

    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)
    

    Which displays that the CHAR and VARCHAR types have different storage methods, but follow the same rules for sheer string comparison. Trailing spaces are ignored; while leading spaces modify the string itself.

    0 讨论(0)
提交回复
热议问题