比较一个字符串前面有空格而另一个没有空格的字符串



如果我必须找到一个字符串名称"Akito",它位于表foo中,那么以下是正常过程,

select * from foo where `name = 'Akito'`

我试着检查它的两个变体,

工作得很好

select * from foo where name = 'Akito   '

Did not Worked Fine

select * from foo where name = '    Akito'

谁能解释一下为什么第二个不工作?

Thanks in advance

CHAR类型使用空字节将字符串填充到字段的长度(而VARCHAR添加分隔符以指示字符串的结束-从而忽略末尾的额外数据(我的意思是空字节)),因此在末尾有空格的比较将忽略这些。前导空格是相关的,因为它们改变了字符串本身。请看Christopher的回答

编辑:需要进一步说明

请参阅下面的一些实际测试。VARCHAR类型确实在字符串中添加了空格,而CHAR字段,即使它们用空格填充了字符串的大小,也会在比较期间忽略它们。具体参见LENGTH函数查询的第二行:

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)

MySQL声明CHAR字段的值为'a ',长度只有1个字符。此外,如果我们连接一些数据:

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)

可以看到,由于VARCHAR确实存储字符串结束的位置,因此空间在连接时保留—这对于CHAR类型不成立。现在,请记住前面的LENGTH示例,其中第二行字段a和b的长度不同,我们测试:

mysql> SELECT * FROM test WHERE a=b;
+------+------+
| a    | b    |
+------+------+
| a    | a    | 
| a    | a    | 
|  a   |  a   | 
+------+------+
3 rows in set (0.00 sec)
因此,我们可以总结一下,CHAR数据类型忽略并裁剪其字符串末尾的额外空间,而VARCHAR不会——除了在比较: 期间:
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)

那么,对于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)

显示CHAR和VARCHAR类型具有不同的存储方法,但是对于纯字符串比较遵循相同的规则。后面的空格被忽略;

http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html表示:

特别地,尾随空格是重要的,而对于使用=操作符执行CHAR或VARCHAR比较:

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

尾随表示不领先。

最新更新