こんにちわ、今週末は夏日になるということで外出が楽しみなHashiです。さて、今回はLaravelネタになります。以前GroupByでグループ化したデータの最新レコードを取得する方法(下記事参照)を紹介したのですが、今回はそれに加えて各最新レコードから特定条件に合致するレコードのみ取得する方法を紹介したいと思います。
なお、Laravelとはなんぞやという方は下の記事を参照してください!
環境
今回の環境は下記の通りとなります。
今回の環境
- Laravel 5.5
- MySQL 5.6.37
仕様と要点
まずは、今回の仕様ですが基本的に冒頭でも紹介した以前の記事と同じで下記のようなテーブルがあると仮定します。テーブル名は「status_histories」とします。またモデル名は「StatusHistory」になります。
ID | user_id | status |
---|---|---|
1 | 1 | 未申請 |
2 | 1 | 申請中 |
3 | 1 | 承認 |
4 | 2 | 未申請 |
5 | 2 | 申請中 |
6 | 3 | 未申請 |
このテーブルは上の表のように「id」,「user_id」,「status」という3つのカラムから構成されているテーブルで、見ての通りユーザーのステータス履歴となっています。
求める結果
前回は下表のように「user_id」でグループ化された各最新レコードを抽出しました。
ID | user_id | status |
---|---|---|
3 | 1 | 承認 |
5 | 2 | 申請中 |
6 | 3 | 未申請 |
そして、今回はこの中からさらに条件に合致したデータを取得したいと思います。今回は各ユーザーの最新レコードが「申請中」のデータのみ取得しようと思いますので、求める結果は下表のようになります。
ID | user_id | status |
---|---|---|
5 | 2 | 申請中 |
条件に合致した最新レコードを取得する
さて、早速取得してみたいと思いますが、まずGroup Byでグループ化した各最新レコードは以前の記事でも紹介した通り、サブクエリを使用した下記のコードで取得できます。
StatusHistory::whereIn('id', function($query) {
$query->select(DB::raw('MAX(id) As id'))->from('status_histories')->groupBy('user_id');
})->get();
そして、ここからさらにステータスが「申請中」のデータのみ取得したい場合は、下記のように書くことで取得できます。
StatusHistory::whereIn('id', function($query) {
$query->select(DB::raw('MAX(id) As id'))->from('status_histories')->groupBy('user_id');
})->where('status','申請中')->get();
簡単ですね。まずサブクエリでグループ化した各最新のレコード(ここではMaxを使用)を取得して、取得したものに対してwhere句で条件を追加する感じです。これで期待通りの結果が得られると思います。
まとめ
ということで、今回はLaravelでグループ化した各最新レコードから、さらに特定条件の合致するデータのみを取得する方法を紹介しました。ご参考になれば。
それでは、今回はここまで!Hashiでした。また!
この記事のまとめ
- LaravelにおいてGROUP BYでグループ化した各最新レコードから特定条件に合致したデータを取得する方法