ภาพรวม
เมื่อต้องการเรียงลำดับผลลัพธ์ของ GROUP BY ตามลำดับที่กำหนดเอง (Custom Order) ไม่ใช่ ASC/DESC ธรรมดา ใช้ ORDER BY CASE ... WHEN ... IN() ...
ตัวอย่างสมบูรณ์
1. สร้างตารางและข้อมูล
CREATE TABLE DemoTable (Value VARCHAR(40));
INSERT INTO DemoTable VALUES ('John');
INSERT INTO DemoTable VALUES ('100&101');
INSERT INTO DemoTable VALUES ('Sam');
INSERT INTO DemoTable VALUES ('90');
INSERT INTO DemoTable VALUES ('Mike45');
2. ข้อมูลก่อนเรียง
SELECT * FROM DemoTable;
+---------+
| Value |
+---------+
| John |
| 100&101 |
| Sam |
| 90 |
| Mike45 |
+---------+
3. เรียงตามลำดับที่กำหนด: John, Sam, Mike45, 90, 100&101
SELECT * FROM DemoTable
ORDER BY CASE
WHEN Value IN ('John', 'Sam', 'Mike45') THEN 100
WHEN Value = '90' THEN 101
WHEN Value = '100&101' THEN 102
ELSE 103
END;
4. ผลลัพธ์
+---------+
| Value |
+---------+
| John |
| Sam |
| Mike45 |
| 90 |
| 100&101 |
+---------+
การทำงานของ CASE ใน ORDER BY
CASEประเมินแต่ละแถว คืนค่าตัวเลข (Sort Key)IN()ทดสอบค่าอยู่ในชุดหรือไม่ORDER BYเรียงตาม Sort Key ที่ได้ (น้อยไปมาก)- ค่า ELSE เป็นค่า Default สำหรับค่าที่ไม่ตรงเงื่อนไขไหนเลย
รูปแบบอื่นๆ
ใช้ FIELD() (MySQL Specific - สั้นกว่า)
ORDER BY FIELD(Value, 'John', 'Sam', 'Mike45', '90', '100&101')
FIELD(str, str1, str2, ...) คืนตำแหน่ง (1-based) ของ str ในรายการ ไม่พบ = 0
ใช้ FIND_IN_SET()
ORDER BY FIND_IN_SET(Value, 'John,Sam,Mike45,90,100&101')
MySQL 8.0+: ใช้ CTE กำหนดลำดับ
WITH SortOrder AS (
SELECT 'John' AS Value, 1 AS SortKey UNION ALL
SELECT 'Sam', 2 UNION ALL
SELECT 'Mike45', 3 UNION ALL
SELECT '90', 4 UNION ALL
SELECT '100&101', 5
)
SELECT d.*
FROM DemoTable d
JOIN SortOrder s ON d.Value = s.Value
ORDER BY s.SortKey;
กรณีใช้งานจริง
- เรียง Status: 'Pending', 'Processing', 'Shipped', 'Delivered', 'Cancelled'
- เรียง Priority: 'Critical', 'High', 'Medium', 'Low'
- เรียง Category ตาม Business Logic
สรุป
ใช้ ORDER BY CASE WHEN col IN (...) THEN n ... END หรือ ORDER BY FIELD(col, 'val1', 'val2', ...) เพื่อเรียงกลุ่มข้อมูลตามลำดับที่กำหนดเอง