Khi cột lưu số dưới dạng chuỗi (VARCHAR, CHAR, TEXT), sắp xếp mặc định ORDER BY col sẽ theo thứ tự bảng chữ cái (lexicographic): '10' < '2' < '301'. Để sắp xếp theo giá trị số học, MySQL cho phép nhân cột với 1 (col*1) để ép kiểu ngầm sang số.
Ví dụ minh họa
Tạo bảng cột VARCHAR:
mysql> CREATE TABLE DemoTable1441 (
Id VARCHAR(30)
);
Chèn dữ liệu:
mysql> INSERT INTO DemoTable1441 VALUES ('301');
mysql> INSERT INTO DemoTable1441 VALUES ('23');
mysql> INSERT INTO DemoTable1441 VALUES ('345');
mysql> INSERT INTO DemoTable1441 VALUES ('10');
mysql> INSERT INTO DemoTable1441 VALUES ('38');
Sắp xếp mặc định (theo chữ):
mysql> SELECT * FROM DemoTable1441 ORDER BY Id;
+------+ | Id | +------+ | 10 | | 23 | | 301 | | 345 | | 38 | +------+
Sắp xếp theo giá trị số với *1
mysql> SELECT * FROM DemoTable1441 ORDER BY Id*1;
Kết quả đúng thứ tự số:
+------+ | Id | +------+ | 10 | | 23 | | 38 | | 301 | | 345 | +------+
Giải thích cơ chế
- MySQL tự động chuyển đổi chuỗi sang số khi tham gia phép toán số học (
*,+,-,/). Id*1không thay đổi giá trị số nhưng buộc MySQL đánh giáIdnhư số.- Chuỗi không phải số (VD: 'abc') sẽ chuyển thành
0.
Các cách ép kiểu khác (chuẩn SQL hơn)
| Cú pháp | Chuẩn SQL | Ghi chú |
|---|---|---|
CAST(Id AS UNSIGNED) | Có | Rõ ràng, khuyến khích |
CONVERT(Id, UNSIGNED INTEGER) | Có | Tương tự CAST |
Id + 0 | Không | Tương tự *1, ngắn gọn |
Id*1 | Không | Thông dụng trong MySQL |
⚠️ Cảnh báo hiệu năng
Sử dụng biểu thức (col*1, CAST(...)) trong ORDER BY làm mất index trên cột đó. Giải pháp tốt nhất: lưu cột ở kiểu số (INT, BIGINT, DECIMAL) ngay từ đầu.