MySQL ORDER BY FIELD

MySQLにおいてorder byしたときにある特定データだけ順番を変えたいってときに便利な関数が FIELD

普通にid昇順で並べるとこう(rails consoleを通してActiveRecord経由でSQLを発行)。

> User.order(:id).ids
   SELECT `users`.`id` FROM `users` ORDER BY `users`.`id` ASC
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]

末尾に特定のIDを持ってくる

FIELD を使って id: 1 を例外として末尾に持っていきたいときのSQLはこう。

> User.order(Arel.sql("FIELD(id, 1)")).ids
   (1.9ms)  SELECT `users`.`id` FROM `users` ORDER BY FIELD(id, 1)
=> [2, 3, 4, 5, 6, 7, 8, 9, 1]

複数のIDを指定する

カンマで値を書き連ねればその順番通りに値が取得できる。

> User.order(Arel.sql("FIELD(id, 1, 2)")).ids
   (1.2ms)  SELECT `users`.`id` FROM `users` ORDER BY FIELD(id, 1, 2)
=> [3, 4, 5, 6, 7, 8, 9, 1, 2]

先頭に特定のIDを複数持ってくる

> User.order(Arel.sql"FIELD(id, 5, 6, id)").ids
   (1.1ms)  SELECT `users`.`id` FROM `users` ORDER BY FIELD(id, 5, 6, id)
=> [5, 6, 1, 2, 3, 4, 7, 8, 9]

参考

MySQL :: MySQL 8.0 Reference Manual :: 12.8 String Functions and Operators