問題:WHERE id IN (2,1,3) 查出順序為 1,2,3 (自然序),但需保持 IN 列表順序 2,1,3。
SELECT * FROM t WHERE id IN (2,1,3)
ORDER BY FIND_IN_SET(id, '2,1,3');
FIND_IN_SET(str, strlist) 回傳 str 在逗號分隔字串 strlist 中的位置 (1-based),找不到回傳 0。
FIND_IN_SET 無法使用索引,資料量大時會全表掃描CASE WHEN 產生排序欄位
SELECT * FROM t WHERE id IN (2,1,3)
ORDER BY CASE id WHEN 2 THEN 1 WHEN 1 THEN 2 WHEN 3 THEN 3 ELSE 4 END;
優化器可能將 CASE 轉為常數排序,配合 WHERE id IN (...) 索引範圍掃描。
-- 前端傳入排序順序 '3,1,2'
SET @order = '3,1,2';
PREPARE stmt FROM 'SELECT * FROM t WHERE id IN (?) ORDER BY FIND_IN_SET(id, ?)';
EXECUTE stmt USING @ids, @order;
記住:IN 列表順序 ≠ 結果順序,需顯式 ORDER BY 指定。