Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

MySQL ORDER BY với thứ tự tùy chỉnh: một số DESC, số ASC?

Giải pháp: FIELD() hoặc CASE

Hàm FIELD(value, val1, val2, ...) trả về vị trí (1-based) của value trong danh sách, hoặc 0 nếu không có. Dùng để sắp xếp tùy chỉnh.

Ví dụ minh họa

Tạo bảng và dữ liệu

mysql> CREATE TABLE DemoTable (Value INT);
mysql> INSERT INTO DemoTable VALUES(10), (70), (60), (56), (81), (85);

Dữ liệu gốc

+-------+
| Value |
+-------+
| 10    |
| 70    |
| 60    |
| 56    |
| 81    |
| 85    |
+-------+

Yêu cầu: 60, 70, 81 xếp trước (DESC), còn lại ASC

mysql> SELECT * FROM DemoTable 
    -> ORDER BY FIELD(Value, 60, 70, 81) DESC;

Kết quả

+-------+
| Value |
+-------+
| 81    |  <-- FIELD=3 (cao nhất) → DESC lên đầu
| 70    |  <-- FIELD=2
| 60    |  <-- FIELD=1
| 10    |  <-- FIELD=0 → cuối, ASC
| 56    |
| 85    |
+-------+

Giải thích FIELD()

  • FIELD(60, 60,70,81) = 1
  • FIELD(70, 60,70,81) = 2
  • FIELD(81, 60,70,81) = 3
  • FIELD(10, 60,70,81) = 0 (không có trong list)
  • DESC: 3, 2, 1, 0 → 81, 70, 60, (còn lại)

So sánh FIELD() vs CASE

Phương phápVí dụƯu điểm
FIELD()ORDER BY FIELD(col, 3,1,2) DESCNgắn gọn, đọc dễ, danh sách giá trị
CASEORDER BY CASE col WHEN 3 THEN 1 WHEN 1 THEN 2 ELSE 3 ENDLinh hoạt điều kiện phức tạp
FIND_IN_SETORDER BY FIND_IN_SET(col, '3,1,2') DESCChuỗi CSV, nhưng chậm hơn

Mở rộng: Sắp xếp phức tạp

-- Ưu tiên status, sau đó ngày
ORDER BY 
    FIELD(status, 'urgent', 'high', 'normal') DESC,
    created_at ASC;

-- Custom order cho category
ORDER BY 
    CASE category 
        WHEN 'premium' THEN 1
        WHEN 'standard' THEN 2
        ELSE 3
    END,
    price DESC;

Lưu ý hiệu năng

  • FIELD()/CASE không dùng index cho ORDER BY
  • Bảng lớn: cân nhắc thêm cột sort_order INT pre-computed
  • Hoặc dùng ORDER BY (col IN (60,70,81)) DESC, col ASC cho boolean sort