Kiểu ENUM trong MySQL sắp xếp mặc định theo thứ tự định nghĩa (không phải giá trị chữ cái). Để sắp xếp theo thứ tự nghiệp vụ tùy ý (VD: A, K, Q, J cho bài), dùng ORDER BY CASE gán trọng số cho từng giá trị ENUM.
Ví dụ minh họa
Tạo bảng cột ENUM (thứ tự định nghĩa: K, J, A, Q):
mysql> CREATE TABLE DemoTable1461 (
DeckOfCards ENUM('K', 'J', 'A', 'Q')
);
Chèn dữ liệu:
mysql> INSERT INTO DemoTable1461 VALUES ('K');
mysql> INSERT INTO DemoTable1461 VALUES ('A');
mysql> INSERT INTO DemoTable1461 VALUES ('J');
mysql> INSERT INTO DemoTable1461 VALUES ('Q');
Dữ liệu (mặc định sắp theo thứ tự ENUM: K, J, A, Q):
mysql> SELECT * FROM DemoTable1461;
+-------------+ | DeckOfCards | +-------------+ | K | | A | | J | | Q | +-------------+
Sắp xếp tùy ý: A → K → Q → J
mysql> SELECT * FROM DemoTable1461
ORDER BY CASE DeckOfCards
WHEN 'A' THEN 100
WHEN 'K' THEN 101
WHEN 'Q' THEN 102
ELSE 103
END;
Kết quả:
+-------------+ | DeckOfCards | +-------------+ | A | | K | | Q | | J | +-------------+
Giải thích
CASE WHEN 'A' THEN 100: Gán trọng số 100 cho 'A' → xếp đầu.WHEN 'K' THEN 101: 'K' xếp sau 'A'.ELSE 103: Các giá trị còn lại ('J') xếp cuối.- Số trọng số bất kỳ miễn là tăng dần theo thứ tự mong muốn.
Cách thay thế: JOIN với bảng mapping
Tạo bảng ánh xạ thứ tự (khuyên dùng cho production, dễ bảo trì):
CREATE TABLE CardOrder (
CardValue CHAR(1) PRIMARY KEY,
SortOrder INT
);
INSERT INTO CardOrder VALUES ('A', 1), ('K', 2), ('Q', 3), ('J', 4);
SELECT d.* FROM DemoTable1461 d
JOIN CardOrder c ON d.DeckOfCards = c.CardValue
ORDER BY c.SortOrder;
So sánh
| Cách | Ưu điểm | Nhược điểm |
|---|---|---|
ORDER BY CASE | Nhanh, không cần bảng phụ, phù hợp ad-hoc | Hard-code logic trong query, khó bảo trì nếu thay đổi thường xuyên |
| JOIN bảng mapping | Tách data/logic, dễ cập nhật, tái sử dụng | Cần join thêm, hơi phức tạp |
| FIELD() | ORDER BY FIELD(DeckOfCards, 'A','K','Q','J') - ngắn gọn MySQL | Chỉ MySQL, không chuẩn SQL |
Lưu ý về ENUM
- ENUM sắp xếp theo thứ tự khai báo, không theo alphabet.
- ENUM lưu trữ dưới dạng số nguyên nội bộ (1, 2, 3...) → tiết kiệm dung lượng.
- Thay đổi giá trị ENUM (ADD/DROP) cần
ALTER TABLE— có thể khóa bảng lớn. - Cân nhắc dùng
VARCHAR+CHECK CONSTRAINT(MySQL 8.0.16+) hoặc bảng tham chiếu (lookup table) cho linh hoạt hơn.