ใช้ฟังก์ชัน FIND_IN_SET() ใน ORDER BY เพื่อจัดลำดับผลลัพธ์ตามลำดับที่ระบุใน IN clause
ไวยากรณ์
SELECT * FROM yourTableName WHERE id IN (val1, val2, val3) ORDER BY FIND_IN_SET(id, 'val1,val2,val3');
สร้างตารางตัวอย่าง
mysql> CREATE TABLE returnRecordSetOrderDemo (
-> Id INT,
-> Name VARCHAR(20)
-> );
เพิ่มข้อมูลตัวอย่าง (Id ไม่เรียงลำดับ)
mysql> INSERT INTO returnRecordSetOrderDemo VALUES (100, 'John'), (130, 'Carol'), (103, 'Bob'), (134, 'Sam'), (102, 'Larry'), (145, 'David');
แสดงข้อมูลทั้งหมด
mysql> SELECT * FROM returnRecordSetOrderDemo;
ผลลัพธ์:
+------+-------+ | Id | Name | +------+-------+ | 100 | John | | 130 | Carol | | 103 | Bob | | 134 | Sam | | 102 | Larry | | 145 | David | +------+-------+
Query ใช้ IN และ ORDER BY FIND_IN_SET
mysql> SELECT * FROM returnRecordSetOrderDemo
-> WHERE Id IN (100, 145, 103, 130)
-> ORDER BY FIND_IN_SET(Id, '100,145,103,130');
ผลลัพธ์ (เรียงตามลำดับใน IN: 100, 145, 103, 130):
+------+-------+ | Id | Name | +------+-------+ | 100 | John | | 145 | David | | 103 | Bob | | 130 | Carol | +------+-------+
อธิบาย FIND_IN_SET(str, strlist)
- คืนค่าตำแหน่ง (1-based index) ของ
strในstrlist(คั่นด้วยคอมม่า) - คืนค่า 0 ถ้าไม่พบ
- คืนค่า NULL ถ้าพารามิเตอร์ใดเป็น NULL
ข้อจำกัด
strlistต้องเป็นสตริงคงที่ (constant string) ไม่สามารถใช้คอลัมน์ได้- เหมาะกับรายการสั้น (< 1000 ค่า) รายการยาวจะช้า
- ทำงานกับสตริง ไม่ใช่ตัวเลข (แปลงอัตโนมัติแต่ควรระวัง)
วิธีอื่น (MySQL 8.0+)
-- ใช้ VALUES() และ ROW_NUMBER()
WITH ordered_ids AS (
SELECT 1 AS pos, 100 AS id UNION ALL
SELECT 2, 145 UNION ALL
SELECT 3, 103 UNION ALL
SELECT 4, 130
)
SELECT t.* FROM returnRecordSetOrderDemo t
JOIN ordered_ids o ON t.Id = o.id
ORDER BY o.pos;