Sắp xếp cột VARCHAR chứa số theo giá trị số học trong MySQL
Cột VARCHAR lưu số sẽ bị sắp xếp theo thứ tự từ điển (lexicographic): '10' < '100' < '110' < '2000'. Để sắp xếp đúng giá trị số, cần CAST sang kiểu số trong ORDER BY.
Ví dụ minh họa
Tạo bảng DemoTable726:
mysql> CREATE TABLE DemoTable726 (Value VARCHAR(100)); Query OK, 0 rows affected (0.60 sec)
Chèn dữ liệu:
mysql> INSERT INTO DemoTable726 VALUES('100');
Query OK, 1 row affected (0.18 sec)
mysql> INSERT INTO DemoTable726 VALUES('10');
Query OK, 1 row affected (0.15 sec)
mysql> INSERT INTO DemoTable726 VALUES('110');
Query OK, 1 row affected (0.17 sec)
mysql> INSERT INTO DemoTable726 VALUES('2000');
Query OK, 1 row affected (0.18 sec)
mysql> INSERT INTO DemoTable726 VALUES('1000');
Query OK, 1 row affected (0.14 sec)
Xem dữ liệu gốc (thứ tự chèn):
mysql> SELECT * FROM DemoTable726;
+-------+ | Value | +-------+ | 100 | | 10 | | 110 | | 2000 | | 1000 | +-------+ 5 rows in set (0.00 sec)
Sắp xếp TĂNG DẦN theo giá trị số (CAST sang DECIMAL):
mysql> SELECT * FROM DemoTable726 ORDER BY CAST(Value AS DECIMAL(20,2));
Kết quả (10, 100, 110, 1000, 2000):
+-------+ | Value | +-------+ | 10 | | 100 | | 110 | | 1000 | | 2000 | +-------+ 5 rows in set (0.00 sec)
Sắp xếp GIẢM DẦN theo giá trị số:
mysql> SELECT * FROM DemoTable726 ORDER BY CAST(Value AS DECIMAL(20,2)) DESC;
Kết quả (2000, 1000, 110, 100, 10):
+-------+ | Value | +-------+ | 2000 | | 1000 | | 110 | | 100 | | 10 | +-------+ 5 rows in set (0.00 sec)
Các kiểu CAST phù hợp
| Kiểu | Cú pháp | Phù hợp cho |
|---|---|---|
| DECIMAL(p,s) | CAST(col AS DECIMAL(20,2)) | Số thập phân, tiền tệ, chính xác |
| UNSIGNED | CAST(col AS UNSIGNED) | Số nguyên dương lớn (0 đến 4.29 tỷ) |
| SIGNED | CAST(col AS SIGNED) | Số nguyên có dấu (-2.14 tỷ đến 2.14 tỷ) |
| DOUBLE | CAST(col AS DOUBLE) | Số thực, khoa học (có sai số floating point) |
Khuyến nghị
- Dùng
DECIMAL(20,2)hoặcUNSIGNEDcho ID, mã số, giá tiền - Nên tạo Generated Column + Index nếu ORDER BY thường xuyên:
Value_num INT GENERATED ALWAYS AS (CAST(Value AS UNSIGNED)) STORED, INDEX(Value_num) - Tránh dùng
CASTtrong WHERE (mất index), hãy chuyển đổi dữ liệu lưu trữ