最新のレコードを含むリレーション付きテーブルの結合とフィルタリング

laravel

この例では、特定の条件に基づいて複数のテーブルを結合し、各ユーザーに対して最新のレコードのみを取得する方法を説明します。

まず、必要なリレーションをロードし、適切なフィールドを選択します。

$records = ExampleModel::with([
    'relation1', 'relation2'
])
->select('main_table.*')

次に、joinSubメソッドを使用して、サブクエリを結合します。このサブクエリは、各ユーザーに対して最新のレコードのみを含みます。

->joinSub(function ($query) {
    $query->select('user_id', DB::raw('MAX(timestamp) as max_timestamp'))
        ->from('main_table')
        ->where(function ($query) {
            $query->whereIn('main_table.status', [1, 2])
                ->orWhere(function ($query) {
                    $query->whereIn('main_table.status', [3, 4])
                        ->where('main_table.timestamp', function ($subQuery) {
                            $subQuery->selectRaw('MAX(timestamp)')
                                ->from('main_table');
                        });
                });
        })
        ->groupBy('user_id');
}, 'latest_records', function ($join) {
    $join->on('main_table.user_id', '=', 'latest_records.user_id')
        ->on('main_table.timestamp', '=', 'latest_records.max_timestamp');
})

最後に、必要な条件を適用し、結果を並べ替えます。

->whereHas('relation1', function ($query) use ($variable1) {
    $query->when($variable1, function ($query, $variable1) {
        $query->where('related_table1.field', $variable1);
    });
})
->when($variable2, function ($query) use ($variable2) {
    $query->where('field2', $variable2);
})
->orderBy('timestamp', 'desc');

この方法により、指定された条件を保持しながら、各ユーザーについて最新のレコードのみが取得されます。

コメント

タイトルとURLをコピーしました