Vấn đề
Cột VARCHAR chứa số sắp xếp theo thứ tự chữ (lexicographic): '100' < '20' < '3'.
Giải pháp: Ép kiểu ngầm với + 0
SELECT cot FROM bang ORDER BY cot + 0 DESC;
Ví dụ: RankNumber kiểu VARCHAR
Dữ liệu
+----+-------+------------+ | Id | Name | RankNumber | +----+-------+------------+ | 1 | Larry | -100 | | 2 | John | 50 | | 3 | Bob | 0 | | 4 | Carol | -110 | | 5 | David | 98 | +----+------------+
Sắp xếp DESC (số)
mysql> SELECT RankNumber FROM selectOrderdemo ORDER BY RankNumber + 0 DESC; +------------+ | RankNumber | +------------+ | 98 | | 50 | | 0 | | -100 | | -110 | +------------+
Sắp xếp ASC (số)
mysql> SELECT RankNumber FROM selectOrderdemo ORDER BY RankNumber + 0; +------------+ | RankNumber | +------------+ | -110 | | -100 | | 0 | | 50 | | 98 | +------------+
Lấy toàn bộ cột
mysql> SELECT * FROM selectOrderdemo ORDER BY RankNumber + 0 DESC; +----+-------+------------+ | Id | Name | RankNumber | +----+-------+------------+ | 5 | David | 98 | | 2 | John | 50 | | 3 | Bob | 0 | | 1 | Larry | -100 | | 4 | Carol | -110 | +----+------------+
Tại sao + 0 hoạt động?
- MySQL ép kiểu chuỗi sang số khi thực hiện phép toán số học
'98' + 0 = 98,'-110' + 0 = -110- So sánh số thay vì so sánh chuỗi
Các cách khác
CAST(cot AS UNSIGNED)/CAST(cot AS SIGNED)CONVERT(cot, UNSIGNED)cot * 1(nhân 1)
Lưu ý
- Chuỗi không phải số (abc) → thành 0
- NULL + 0 = NULL (xuất hiện đầu/cuối tùy ASC/DESC)
- Index trên cột VARCHAR không dùng được cho ORDER BY cot + 0
- Khuyến nghị: Dùng kiểu số (INT, DECIMAL) cho cột lưu số