When a Column Is a String
Assume a table has a varchar column. For a simple test, use the player table below.
mysql> desc player;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | varchar(10) | NO | PRI | NULL | |
| name | varchar(20) | YES | | | |
| record | varchar(5) | YES | | | |
| rank | int(11) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
Now insert the following data.
mysql> SELECT id, name, record, rank \
-> FROM player;
+-----+---------+--------+------+
| id | name | record | rank |
+-----+---------+--------+------+
| id1 | chulsoo | 10.63 | 1 |
| id2 | younghee| 8.28 | 2 |
| id3 | jjanggu | 1.20 | 4 |
| id4 | gildong | 7.61 | 3 |
+-----+---------+--------+------+
First, sort by rank, which is an INT column, in ascending order (lower rank value means higher rank).
mysql> SELECT id, name, record, rank \
-> FROM player \
-> ORDER BY rank ASC;
+-----+---------+--------+------+
| id | name | record | rank |
+-----+---------+--------+------+
| id1 | chulsoo | 10.63 | 1 |
| id2 | younghee| 8.28 | 2 |
| id4 | gildong | 7.61 | 3 |
| id3 | jjanggu | 1.20 | 4 |
+-----+---------+--------+------+
The result is correct. Now sort by record, a VARCHAR column, in descending order.
mysql> SELECT id, name, record, rank \
-> FROM player \
-> ORDER BY record DESC;
+-----+---------+--------+------+
| id | name | record | rank |
+-----+---------+--------+------+
| id2 | younghee| 8.28 | 2 |
| id4 | gildong | 7.61 | 3 |
| id1 | chulsoo | 10.63 | 1 |
| id3 | jjanggu | 1.20 | 4 |
+-----+---------+--------+------+
The order is wrong. The value “7.61” is placed second even though “10.63” is larger.
How to Fix It
Here are two ways to sort a varchar column as a number in MySQL.
Use CAST
Use CAST to convert the value explicitly. Combine it with DECIMAL.
mysql> SELECT id, name, record, rank \
-> FROM player \
-> ORDER BY CAST(record AS DECIMAL(4, 2)) DESC;
+-----+---------+--------+------+
| id | name | record | rank |
+-----+---------+--------+------+
| id1 | chulsoo | 10.63 | 1 |
| id2 | younghee| 8.28 | 2 |
| id4 | gildong | 7.61 | 3 |
| id3 | jjanggu | 1.20 | 4 |
+-----+---------+--------+------+
Now the records are sorted correctly.
In DECIMAL(P, D), P is the total number of digits (1 to 65), and D is the number of decimal places. For example, DECIMAL(6, 2) represents values from 9999.99 to -9999.99.
Use Implicit Conversion
You can also rely on implicit conversion by using the + operator on the varchar column.
mysql> SELECT id, name, record, rank \
-> FROM player \
-> ORDER BY record+0 DESC;
+-----+---------+--------+------+
| id | name | record | rank |
+-----+---------+--------+------+
| id1 | chulsoo | 10.63 | 1 |
| id2 | younghee| 8.28 | 2 |
| id4 | gildong | 7.61 | 3 |
| id3 | jjanggu | 1.20 | 4 |
+-----+---------+--------+------+
In the example, record+0 forces numeric conversion, but record*1 works the same way.