2011-09-17 5 views
5

Se devo trovare un nome di stringa "Akito" e si trova nella foo tavolo allora seguendo è la procedura normale,Confronto tra stringhe con uno che ha spazi vuoti prima, mentre l'altro non

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

ho cercato di controllare due variazioni di esso,

funzionava bene

select * from foo where name = 'Akito ' 

non ha Ha funzionato bene

select * from foo where name = ' Akito' 

Qualcuno può spiegare perché il secondo non ha funzionato?

Grazie in anticipo

+1

Se si desidera un metodo (probabilmente) lento per eseguire ciò, utilizzare 'select * da foo dove TRIM (name) = 'Akito'' – leon

+0

@leon: Grazie per questo :) –

risposta

9

tipi CHAR riempire la stringa alla lunghezza del campo con byte nullo (mentre VARCHAR aggiungi delimitatori per indicare la fine della stringa - ignorando così dati extra alla fine (intendo byte vuoto)), e quindi i confronti che hanno spazi alla fine ignoreranno quelli. Gli spazi principali sono rilevanti in quanto alterano la stringa stessa. Vedi la risposta di Christopher.

EDIT: un po 'di ulteriore elaborazione richiesto

Vedi alcune prove pratiche di seguito. I tipi VARCHAR aggiungono spazi alla stringa, mentre i campi CHAR, anche se riempiono la stringa fino alla sua dimensione con spazi, li ignorano durante i confronti. Vedi in particolare la seconda linea con la query LENGTH funzione:

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) 

cui MySQL stabilisce il campo CHAR, con il valore di 'un' come è stato inserito, ha solo 1 carattere di lunghezza. Inoltre, se concatenare una po 'di dati:

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) 

si può vedere che, dal momento che fa VARCHAR negozio dove finisce la stringa, lo spazio rimane su concatenazioni - che non vale per i tipi CHAR.Ora, tenendo presente la LENGTH precedente esempio, dove la linea due ha diverse lunghezze per i suoi campi a e b, ci prova:

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

Pertanto, possiamo riassumere che indica che il tipo di dati CHAR ignora e finiture di spazio in più a la fine della sua corda, mentre VARCHAR non lo fa - tranne durante il confronto:

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) 

Quindi, è lo stesso vale per il 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) 

che mostra che i tipi CHAR e VARCHAR hanno diversi metodi di archiviazione, ma seguire le stesse regole per il confronto pura stringa. Gli spazi finali vengono ignorati; mentre gli spazi iniziali modificano la stringa stessa.

+0

Per favore, per favore, cosa intendi? "ignorando dati extra alla fine"? Gli spazi non dovrebbero essere considerati la parte della stringa? –

+1

@ Akito, ha chiarito il mio punto? – leon

+0

Disturbare il modo in cui i VARCHARS mantengono i loro spazi finali ** ma li ignorano durante i confronti **. Ho appena incontrato un problema con questo comportamento. – Timo

7

http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html dice il seguente:

In particolare, gli spazi finali sono significativi, che non è vero per CHAR o comparazioni VARCHAR eseguite con l'operatore =:

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

Trailing significa non condurre. Quelli sembrano essere rilevanti.

Problemi correlati