🔥

[Laravel]ランクでソートをする方法+子テーブルでソートする方法

2022/12/15に公開

はじめに

子テーブルにあるS,A,Bのようなランクでソートをかける時に苦戦をしたので、その方法を解説します。

以下のテーブルがある前提で、このテーブルのソートについて解説していきます。
usersとuser_detailsは1対1の関係です

users
id
name
user_details
id
user_id
rank

ランクでソートする方法

ランクでソートをするにはLaravelのorderbyRawを使用します。
ランクはS,A,Bという値があり、昇順でソートする場合は以下のようになります。

UserDetail::orderByRaw("CASE rank
 WHEN 'S' THEN 1 WHEN 'A' THEN 2 WHEN 'B' THEN 3 END ASC");
")->get()

子テーブル+ランクでソートする方法

以下のようにselectで子テーブルの項目を抽出してから、その値でソートをかければできます。(selectを使用すれば、リレーションの使用ができます)

User::select('users.*', DB::raw('(SELECT rank FROM user_details WHERE users.id = user_details.appointment_id ) as sort_rank'))
->orderByRaw("CASE sort_rank
 WHEN 'S' THEN 1 WHEN 'A' THEN 2 WHEN 'B' THEN 3 END ASC");
")->get()

終わりに

今回、子テーブルのソートの時にjoin()を使用してもよかったのですが、リレーションが使用できなくなってしまうため、selectを使用しました。
また、with()も使用する方法が考えられましたが、with()は最後にget()を呼び出した時にリレーション先のテーブルを結合するので、クエリビルダーのみで書くことができず、get()の後にコレクションメソッドを駆使しながらソートする羽目になりそうなので使用しませんでした。

他にいい方法などありましたら教えていただけると幸いです。

Discussion