まえがき
ソートするときに、idの昇順・降順ではなく、任意の順番でソートしたい機会があったので、その方法のメモです。
生SQLとRailsで書くときの2パターンを記載しておきます。
(Mysqlだと、FIELD
が使えるのですが、Postgresqlだとそれに類するものが無いっぽくて、CASE
で実現する方法くらいしか見つかりませんでした。)
説明に使うテーブル
animals
テーブル
id | name |
---|---|
1 | dog |
2 | cat |
3 | bird |
ソート方法
生SQLで取得する場合と、Railsでの書き方を記載する。
昇順で取得したい場合
sql
SELECT
*
FROM
animals
ORDER BY
id ASC
rails
Animals.order(id: :asc)
降順で取得したい場合
sql
SELECT
*
FROM
animals
ORDER BY
id DESC
rails
Animals.order(id: :desc)
任意の順番で取得したい場合(本題)
e.g ) idが 2, 3, 1
の順番に取得したいとする
sql
SELECT
*
FROM
animals
ORDER BY
CASE id
WHEN 2 THEN 1
WHEN 3 THEN 2
WHEN 1 THEN 3
END
rails
# ORDER BY 句のクエリを生成(可読性は...)
def order_query(column_values)
column_values.each.with_index(1).inject('CASE id ') do |order_query, (column_value, index)|
order_query << "WHEN #{column_value} THEN #{index} "
end << 'END'
end
animal_ids = [2, 3, 1]
Animal.order(order_query(animal_ids))