Значения в предикате IN()
считаются набором, а результат, возвращаемый SQL-запросом, не может автоматически определить порядок из этого набора.
Как правило, порядок любого запроса SQL является произвольным , если только не указан порядок с предложением ORDER BY
.
Вы можете использовать функцию MySQL FIND_IN_SET()
, чтобы делать то, что вы хотите:
SELECT * FROM foo f where f.id IN (2, 3, 1)
ORDER BY FIND_IN_SET(f.id, '2,3,1');
Обратите внимание, что аргумент списка для FIND_IN_SET()
не является списком переменной длины, как аргументы IN()
. Это должен быть строковый литерал или SET
.
Ответы на вопросы о производительности: мне тоже любопытно, поэтому я попробовал оба метода FIND_IN_SET()
и FIELD()
для моей копии данных StackOverflow:
Без индекса на VoteTypeId:
SELECT * FROM Votes ORDER BY FIND_IN_SET(VoteTypeId, '13,1,12,2,11,3,10,4,9,5,8,6,7');
3618992 rows in set (31.26 sec)
3618992 rows in set (29.67 sec)
3618992 rows in set (28.52 sec)
SELECT * FROM Votes ORDER BY FIELD(VoteTypeId, 13,1,12,2,11,3,10,4,9,5,8,6,7);
3618992 rows in set (37.30 sec)
3618992 rows in set (49.65 sec)
3618992 rows in set (41.69 sec)
С индексом VoteTypeId:
SELECT * FROM Votes ORDER BY FIND_IN_SET(VoteTypeId, '13,1,12,2,11,3,10,4,9,5,8,6,7');
3618992 rows in set (14.71 sec)
3618992 rows in set (14.81 sec)
3618992 rows in set (25.80 sec)
SELECT * FROM Votes ORDER BY FIELD(VoteTypeId, 13,1,12,2,11,3,10,4,9,5,8,6,7);
3618992 rows in set (19.03 sec)
3618992 rows in set (14.59 sec)
3618992 rows in set (14.43 sec)
Вывод: при ограниченном тестировании нет большого преимущества ни для одного из методов.