何がしたかった・・・?
laravelのクエリビルダにてorderbyを複数使いたかったんです。
以下のコードは一部公式リファレンスにならった感じのやつですが、usersテーブルから値を取得する際にまずnameカラムでソートした後、同名のものがある場合は、同名の物のみ、さらにold(年齢)でソートすると言う感じです。
$users = DB::table('users')
->orderBy('name')
->orderBy('old')
->get();
一般的には上記のように二つチェインさせてあげれば大丈夫ですが...
ふと、これって省略できないの・・・?と思ったわけです。
whereでいくところのwhereInをやりたいなって感じです!
まぁ、別に上記の方法でもいいんですが、せっかくなので調べてみました...!
どうやればいい?
さて、では複数カラムにorderbyを適応するにはどんな方法があるんでしょうか・・・?
みていきましょう!
orderbyを複数つなげる
まず最初は先ほども見たorderbyをチェインで二以上つなげてしまうやつですね。
$users = DB::table('users')
->orderBy('name')
->orderBy('old')
->get();
現状一番簡単で一番使われてる方法でしょう。
orderByRawを使う
MyTable::orderByRaw("coloumn1 DESC, coloumn2 ASC");
->get();
orderByRawメソッドを使えば上記のように書くことで以下のようなSQLを発行できるようです。
SELECT * FROM `my_tables` ORDER BY `coloumn1` DESC, `coloumn2` ASC
独自のスコープを作っちゃう
海外のQAにて回答されていたものですが、以下のようにモデルにスコープを定義してしまおう!ってやつです。
public function scopeOfSort($query, $sort)
{
foreach ($sort as $column => $direction) {
$query->orderBy($column, $direction);
}
return $query;
}
こうすることで複数カラムに対しても独自の方法でアプローチすることができます!
どれがいいんだろう・・・?
細かい速度等の考察はできていませんが、現時点ではざっと上記の3つの手法があるかなぁ〜?って感じでした。
僕の勤める会社のプログラムでは最初の、そのまま連結させる手法が主に使われているようでしたが、orderByRaw辺りでもいいかもなぁと。
一般的かはおいておいて...スコープとして作っておけば将来的にorderbyの仕様変更された時とかの修正箇所がスコープ側だけで済んでらっきー!なんてことは考えられたりもするのかな・・・?
ただ、独自のスコープを作ると、知らない人が読む時にむむ?っとはなるかもですね。
どれをつかうにしても、複数人で開発するならどの手法を使うか事前に揃えておいたほうがいいでしょう。
また、一番無難なのはQAやらサイトなんかでも回答に上がっていた省略無しのチェインで繋ぐ手法だと思います。
あくまで体感ですが、調べていて一番目にしましたので。
まとめ
っというわけで、今回はorderbyで複数カラムをソートする方法を見ていきました。
書くためにつかわずとも、知識として知っておけば突然出てきてもさらっと読めるので、頭の片隅には入れておきたいですね!
それでわっ!