简体   繁体   English

与 MySQL 中尾随空格的比较

[英]Comparison with trailing spaces in MySQL

This SQL query:此 SQL 查询:

select c1 from table where c1='';

returns rows that have c1=' ' (one empty space) in MySQL.返回 MySQL 中具有c1=' ' (一个空格)的行。

Is this intended or a bug?这是故意的还是错误?

EDIT: please check SQL Fiddle link here , and the number of spaces in SELECT query doesn't matter.编辑:请在此处检查 SQL Fiddle 链接, SELECT查询中的空格数无关紧要。

It's all stated there in the documentation.这一切都在文档中说明。 I've quoted the important points here.我在这里引用了重要的观点。 But I would suggest to go through the full documentation但我建议阅读完整的文档

VARCHAR values are not padded when they are stored. VARCHAR 值在存储时不会被填充。 Trailing spaces are retained when values are stored and retrieved, in conformance with standard SQL.根据标准 SQL,在存储和检索值时保留尾随空格。

On the other hand, CHAR values are padded when they are stored but trailing spaces are ignored when retrieved.另一方面,CHAR 值在存储时会被填充,但在检索时会忽略尾随空格。

在此处输入图片说明

All MySQL collations are of type PADSPACE.所有 MySQL 归类都是 PADSPACE 类型。 This means that all CHAR, VARCHAR, and TEXT values in MySQL are compared without regard to any trailing spaces.这意味着比较 MySQL 中的所有 CHAR、VARCHAR 和 TEXT 值,而不考虑任何尾随空格。 “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant.此上下文中的“比较”不包括 LIKE 模式匹配运算符,对于其尾随空格很重要。

Explanation: Trailing spaces are ignored while comparing strings using comparison operator ('=').说明:使用比较运算符 ('=') 比较字符串时,会忽略Trailing spaces But trailing spaces are significant for LIKE ( pattern matching operator )但是尾随空格对于LIKEpattern matching operator )很重要

If your column is from type CHAR and not VARCHAR, than this is correct.如果您的列来自CHAR类型而不是 VARCHAR,那么这是正确的。 On CHAR-Fields will trailing blanks on comparing ignored!在 CHAR-Fields 上将忽略比较时的尾随空白! So所以

field = ''
field = '    '

are the same.是相同的。

This is documented behaviour.这是记录在案的行为。

The MySQL documentation for LIKE mentions LIKE的 MySQL 文档提到

trailing spaces are significant, which is not true for CHAR or VARCHAR comparisons performed with the = operator:尾随空格很重要,这对于使用 = 运算符执行的 CHAR 或 VARCHAR 比较而言并非如此:

SQL Server works the same way. SQL Server 的工作方式相同。

This behavior is in accordance with ANSI SQL-92 standard.此行为符合 ANSI SQL-92 标准。 Any database conforming to this standard will exhibit same behavior.任何符合此标准的数据库都将表现出相同的行为。 Quote:引用:

 3) The comparison of two character strings is determined as fol- lows: a) If the length in characters of X is not equal to the length in characters of Y, then the shorter string is effectively replaced, for the purposes of comparison, with a copy of itself that has been extended to the length of the longer string by concatenation on the right of one or more pad char- acters, where the pad character is chosen based on CS. If CS has the NO PAD attribute, then the pad character is an implementation-dependent character different from any char- acter in the character set of X and Y that collates less than any string under CS. Otherwise, the pad character is a <space>. b) The result of the comparison of X and Y is given by the col- lating sequence CS.

So, according to these specs 'abc' = 'abc ' and '' = ' ' evaluate to true (but '' = '\\t' is false).因此,根据这些规范'abc' = 'abc ''' = ' '评估为真(但'' = '\\t'为假)。

If c1 is CHAR(1) , then this is correct, as CHAR columns are fixed width and will be filled with blanks if necessary.如果c1CHAR(1) ,那么这是正确的,因为CHAR列是固定宽度的,如有必要,将用空格填充。

So even if you put '' into a CHAR(1) field you will get ' ' upon SELECT ing.因此,即使您将''放入CHAR(1)字段中,您也会在SELECT得到' ' Also, filtering for an empty string will yield ' ' .此外,过滤空字符串将产生' '

Please accept Martin Smith's answer, as he gave the correct hint before me .请接受马丁史密斯的回答,因为他在我面前给出了正确的提示

Also, as per MySQL documentation , trailing whitespace is ignored when comparing strings with = , so if your c1 column contains only spaces (or one in your case), it will be returned even though you filter WHERE c1 = '' : 此外,根据 MySQL 文档,将字符串与 =进行比较时会忽略尾随空格,因此如果您的 c1列仅包含空格(或在您的情况下包含空格),即使您过滤 WHERE c1 = ''也会返回它:

In particular, trailing spaces are significant, which is not true for CHAR or VARCHAR comparisons performed with the = operator 特别是,尾随空格很重要,这对于使用 = 运算符执行的 CHAR 或 VARCHAR 比较而言并非如此

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

尝试这个 -

Select case when c1 = '' then ' ' else c1 end from table ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM