Cú pháp
Sử dụng biểu thức logic trong ORDER BY: giá trị 0 trả về 1 (true), giá trị khác 0 trả về 0 (false). MySQL sắp xếp false (0) trước true (1):
SELECT * FROM ten_bang ORDER BY ten_cot = 0, ten_cot;
Ví dụ chi tiết
1. Tạo bảng
mysql> CREATE TABLE SortColumnZeroAtLastDemo ( -> RankNumber INT -> ); Query OK, 0 rows affected (1.40 sec)
2. Chèn dữ liệu (có nhiều giá trị 0)
mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(100); Query OK, 1 row affected (0.20 sec) mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(0); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(0); Query OK, 1 row affected (0.11 sec) mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(50); Query OK, 1 row affected (0.13 sec) mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(10); Query OK, 1 row affected (0.15 sec) mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(0); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO SortColumnZeroAtLastDemo VALUES(40); Query OK, 1 row affected (0.12 sec)
3. Dữ liệu gốc
mysql> SELECT * FROM SortColumnZeroAtLastDemo;
+------------+ | RankNumber | +------------+ | 100 | | 0 | | 0 | | 50 | | 10 | | 0 | | 40 | +------------+ 7 rows in set (0.00 sec)
4. Sắp xếp: 0 về cuối, các giá trị khác tăng dần
mysql> SELECT * FROM SortColumnZeroAtLastDemo -> ORDER BY RankNumber = 0, RankNumber;
+------------+ | RankNumber | +------------+ | 10 | | 40 | | 50 | | 100 | | 0 | | 0 | | 0 | +------------+ 7 rows in set (0.00 sec)
Giải thích cơ chế
RankNumber = 0là biểu thức boolean: trả về 1 (true) nếu bằng 0, ngược lại 0 (false)- MySQL sắp xếp số: 0 (false) trước 1 (true)
- Do đó: Các hàng có RankNumber ≠ 0 (false=0) lên trước, RankNumber = 0 (true=1) xuống sau
- Trong mỗi nhóm, sắp xếp tiếp theo theo
RankNumbertăng dần
Mở rộng: Xử lý cả NULL
-- NULL và 0 đều về cuối SELECT * FROM ten_bang ORDER BY (ten_cot = 0 OR ten_cot IS NULL), ten_cot;
-- NULL lên đầu, 0 xuống cuối SELECT * FROM ten_bang ORDER BY ten_cot IS NULL DESC, ten_cot = 0, ten_cot;
Ứng dụng thực tế
- Sắp xếp thứ tự ưu tiên: 0 = "không xác định/không ưu tiên"
- Hiển thị sản phẩm: Số lượng 0 (hết hàng) xuống cuối
- Ranking: Điểm 0 (chưa thi đấu) xuống cuối
Lưu ý
- Không thể dùng index cho sắp xếp này (expression-based ordering)
- Hiệu năng tốt trên bảng vừa (< 100k hàng)
- Bảng lớn: Cân nhắc cột computed/generated column + index (MySQL 8.0+)