laravelのhasmanyで、年月日でgroup byして、その日の最新のレコードだけ欲しい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// このビルの更新情報(フロアの更新情報も含ませる) public function history_logs() { // return $this->hasMany(BuildingFloorHistoryLog::class, 'b_code', 'b_code')->orderBy('updated_at','desc'); return $this->hasMany(BuildingFloorHistoryLog::class, 'b_code', 'b_code') ->groupBy('f_code', DB::raw('DATE(check_date)'), 'history_message_kind') // 日時別・種類別 ->select( // group byされていないカラムは、maxにしておけば最新の日付になる。メッセージは同じなのでmaxでも問題なし DB::raw('max(id) as id'), DB::raw('max(b_code) as b_code'), DB::raw('max(f_code) as f_code'), DB::raw('max(history_message) as history_message'), DB::raw('max(check_date) as check_date'), DB::raw('max(created_at) as created_at'), DB::raw('max(updated_at) as updated_at') ) ->orderBy('check_date','desc'); } |
こういうややこしいのは、SQL文の方が楽だな~。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SELECT DATE_FORMAT(T1.check_date,'%Y-%m-%d') as check_date, T1.history_message FROM build_floor_history_log AS T1 INNER JOIN ( -- その日のメッセージ種別毎の最新IDを取得(auto_incrementだから最大が最新) SELECT DATE_FORMAT(check_date,'%Y-%m-%d') as yyyymmdd, history_message_kind, MAX(id) as max_id FROM `build_floor_history_log` WHERE `b_code`= ? group by DATE_FORMAT(check_date,'%Y-%m-%d'), f_code, history_message_kind ) AS T2 ON T2.max_id=T1.id order by T1.check_date DESC |
しかし、やはりlaravel的に書こう
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public function history_logs() { // 先にサブクエリで、groupbyして、最大レコードIDを取得 $subQuery = BuildingFloorHistoryLog::selectRaw('max(id) as id') // 日時別・種類別が同じなら、最新レコードのみ欲しい ->groupBy('f_code', DB::raw('DATE(check_date)'), 'history_message_kind') return $this->hasMany(BuildingFloorHistoryLog::class, 'b_code', 'b_code') // 同じテーブルに別名をつけて、idでjoinして、最新レコードのみを抽出 ->joinSub($subQuery, 'BuildingFloorHistoryLog1', 'BuildingFloorHistoryLog1.id', 'BuildingFloorHistoryLog.id') ->orderby('BuildingFloorHistoryLog.id', 'desc'); } |