在 MySQL 中執行 SELECT * FROM test WHERE id IN (3,1,5) 時,結果預設會按 id 升序排列(即 1, 3, 5)。但實際開發中,我們往往需要結果完全按照 IN 列表裡的順序返回(即 3, 1, 5)。本文整理了兩種在 MySQL 中實現此需求的常用技巧。
FIELD() 函數(推薦)FIELD(str, str1, str2, str3, ...) 函數會返回 str 在後續列表中第一次出現的位置(從 1 開始),若不存在則返回 0。利用此特性配合 ORDER BY 即可輕鬆實現自定義排序:
SELECT * FROM test WHERE id IN (3,1,5) ORDER BY FIELD(id, 3, 1, 5);
此方法語意清晰、效能良好,是 MySQL 官方推薦的標準做法。
FIND_IN_SET() 函數FIND_IN_SET(str, strlist) 用於在以逗號分隔的字符串列表中查找字符串的位置。雖然它的設計初衷是處理集合類型字段,但也可用於此場景:
SELECT * FROM test WHERE id IN (3,1,5) ORDER BY FIND_IN_SET(id, '3,1,5');
注意: FIND_IN_SET 的第二個參數必須是字符串常量,無法直接使用列或變量,且在大數據量時效能略遜於 FIELD()。
SUBSTRING_INDEX()網上流傳一種 ORDER BY SUBSTRING_INDEX('3,1,5', id, 1) 的寫法,實測在某些版本中會產生錯誤排序,且語意晦澀,不建議在生產環境使用。
IN 列表較短(< 100 個值)時,上述方法均可接受。id, sort_order)進行 JOIN 查詢,利用索引提升效能。MySQL 中實現 IN 條件順序排序,首選 ORDER BY FIELD(id, ...),語法標準、可讀性強、效能穩定;FIND_IN_SET 可作為備選方案。避免使用 SUBSTRING_INDEX 等非常規手段。