Sắp xếp theo thứ tự tùy chỉnh với ORDER BY FIELD() trong MySQL
Hàm FIELD(str, val1, val2, ...) trả về vị trí (1-based) của str trong danh sách giá trị. Kết hợp với ORDER BY FIELD(...) ASC để sắp xếp theo thứ tự chính xác như danh sách cung cấp.
Ví dụ minh họa
Tạo bảng DemoTable:
mysql> CREATE TABLE DemoTable (Title VARCHAR(100)); Query OK, 0 rows affected (0.56 sec)
Chèn dữ liệu:
mysql> INSERT INTO DemoTable VALUES('Java');
Query OK, 1 row affected (0.14 sec)
mysql> INSERT INTO DemoTable VALUES('C');
Query OK, 1 row affected (0.17 sec)
mysql> INSERT INTO DemoTable VALUES('Python');
Query OK, 1 row affected (0.63 sec)
mysql> INSERT INTO DemoTable VALUES('MongoDB');
Query OK, 1 row affected (0.20 sec)
Xem dữ liệu gốc:
mysql> SELECT * FROM DemoTable;
+---------+ | Title | +---------+ | Java | | C | | Python | | MongoDB | +---------+ 4 rows in set (0.00 sec)
Sắp xếp theo thứ tự: MongoDB, C, Python, Java:
mysql> SELECT * FROM DemoTable ORDER BY FIELD(Title, 'MongoDB', 'C', 'Python', 'Java') ASC;
Kết quả (thứ tự ngược với mong đợi do ví dụ gốc có lỗi logic):
+---------+ | Title | +---------+ | Java | | C | | Python | | MongoDB | +---------+ 4 rows in set (0.00 sec)
Lưu ý: Ví dụ gốc có lỗi - FIELD trả về 1 cho 'MongoDB', 2 cho 'C', 3 cho 'Python', 4 cho 'Java'. ORDER BY ASC sẽ cho MongoDB đầu, Java cuối. Kết quả in ra ngược lại có thể do lỗi copy paste.
Kết quả đúng mong đợi
+---------+ | Title | +---------+ | MongoDB | | C | | Python | | Java | +---------+
Cú pháp FIELD()
FIELD(giá_trị_cần_tìm, giá_trị_1, giá_trị_2, ..., giá_trị_N) -- Trả về: 1 nếu = giá_trị_1, 2 nếu = giá_trị_2, ... 0 nếu không tìm thấy
Ứng dụng thực tế
- Sắp xếp trạng thái:
ORDER BY FIELD(status, 'pending', 'processing', 'shipped', 'delivered', 'cancelled') - Sắp xếp độ ưu tiên:
ORDER BY FIELD(priority, 'critical', 'high', 'medium', 'low') - Sắp xếp enum tùy chỉnh:
ORDER BY FIELD(type, 'premium', 'standard', 'basic')
Xử lý giá trị KHÔNG trong danh sách FIELD
Giá trị không có trong FIELD() trả về 0 → sẽ xếp ĐẦU TIÊN khi ASC, CUỐI khi DESC.
-- Đẩy giá trị không xác định xuống cuối:
ORDER BY CASE WHEN FIELD(Title, 'MongoDB', 'C', 'Python', 'Java') = 0 THEN 1 ELSE 0 END,
FIELD(Title, 'MongoDB', 'C', 'Python', 'Java')
Hiệu suất
FIELD()không sử dụng index → full table scan- Bảng lớn: Tạo cột
sort_order INT, cập nhật bằng trigger/app, index cột này - Hoặc JOIN với bảng mapping thứ tự