8

This SQL query:

select c1 from table where c1='';

returns rows that have c1=' ' (one empty space) in MySQL.

Is this intended or a bug?

EDIT: please check SQL Fiddle link here, and the number of spaces in SELECT query doesn't matter.

1000111
  • 13,169
  • 2
  • 28
  • 37
boh
  • 1,477
  • 2
  • 16
  • 35

7 Answers7

6

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. Trailing spaces are retained when values are stored and retrieved, in conformance with standard SQL.

On the other hand, CHAR values are padded when they are stored but trailing spaces are ignored when retrieved.

enter image description here

All MySQL collations are of type PADSPACE. This means that all CHAR, VARCHAR, and TEXT values in MySQL are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant.

Explanation: Trailing spaces are ignored while comparing strings using comparison operator ('='). But trailing spaces are significant for LIKE (pattern matching operator)

1000111
  • 13,169
  • 2
  • 28
  • 37
  • I saw your explanation, and I have this exact problem, I have a trailing space in one field but my like '% ' script somehow doesn't catch it. Do you know why this is? – Vladimir Despotovic Jun 26 '20 at 09:49
  • Can you check the length of the string and be certain about your claim? `select length(string) ; select char_length(string)` @VladimirDespotovic – 1000111 Jun 27 '20 at 14:59
  • i did. All bad. Not good. It is completely wrong also when you compare string length using LENGTH() – Vladimir Despotovic Jun 27 '20 at 15:00
  • Did you try with `char_length` too? @VladimirDespotovic You'd better share an SQLFIDDLE putting your mysterious data there. It will be easier to reproduce the problem then. – 1000111 Jun 27 '20 at 15:04
3

If your column is from type CHAR and not VARCHAR, than this is correct. On CHAR-Fields will trailing blanks on comparing ignored! So

field = ''
field = '    '

are the same.

Frank
  • 1,901
  • 20
  • 27
  • 2
    Actually this is not quite true. VARCHAR doesn't "ignore" trailing blanks. If you add them, they will be there. But CHAR fields are fixed width. So a CHAR(5) field will **always** be 5 chars (filled with blanks if necessary). – Thorsten Dittmar Sep 19 '16 at 11:51
  • I am using `varchar` – boh Sep 19 '16 at 12:53
  • @boh Trailing whitespace is ignored when comparing with `=`. – Thorsten Dittmar Sep 19 '16 at 12:57
  • @ThorstenDittmar That's what I guess but I can't confirm, would appreciate if you can give a reference source, thanks. – boh Sep 19 '16 at 13:03
  • @Thorsten the question is a SELECT Not a INSERT. – Frank Sep 22 '16 at 09:07
  • @Frank Well, you inserted "on comparing" in your last edit. Only that makes your answer correct. Still, when you select a `CHAR(5)` field, the result will always be 5 characters, not matter how long the actual content is. This is different with `VARCHAR` fields. – Thorsten Dittmar Sep 22 '16 at 09:30
3

This is documented behaviour.

The MySQL documentation for LIKE mentions

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

SQL Server works the same way.

Martin Smith
  • 438,706
  • 87
  • 741
  • 845
2

This behavior is in accordance with ANSI SQL-92 standard. 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).

Salman A
  • 262,204
  • 82
  • 430
  • 521
1

If c1 is CHAR(1), then this is correct, as CHAR columns are fixed width and will be filled with blanks if necessary.

So even if you put '' into a CHAR(1) field you will get ' ' upon SELECTing. 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 = '':

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)

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
-2
select c1, length(c1) as l
from table t_name 
group by l

(figur eht oot)

Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
series0
  • 7
  • 1
-3

Try this -

Select case when c1 = '' then ' ' else c1 end from table ;
djv
  • 15,168
  • 7
  • 48
  • 72
  • What's this supposed to help? – Thorsten Dittmar Sep 19 '16 at 12:36
  • It will convert your empty **('')** to **' '** . Else it will return whatever string you have in that column. I think it was asked in this ? – Palak Nagar Sep 19 '16 at 12:40
  • Why would you want that? The original question is not to return `' '` when the column is empty but why `WHERE c1 = ''` also returns columns that contain `' '`. So no, this is not an answer to the question. Please read the question again. – Thorsten Dittmar Sep 19 '16 at 12:41