Laravel7 From句にサブクエリ(副問合せ)

こんなテーブルがあった場合

■メンバーテーブルmembers
id
name

■記事テーブルarticles
id
member_id
title
public_date
is_public

単純に内部結合の場合

メンバーの記事を取得
m.id = articles.member_idのレコード

->join('articles as a', 'a.member_id', '=', 'm.id')

条件を指定して内部結合の場合

記事テーブルから公開中のレコードのみ抽出対象としたい場合クロージャを使う

->join('article as a', function($join){
    $join->on('a.member_id', '=', 'm.id')
        ->where('a.is_public', '=', 1);  // 公開中
})

もっと複雑な条件で記事テーブルを抽出して内部結合の場合

例えば、記事テーブルから公開中の記事をメンバーごとに最新の記事の日付を抽出して、メンバーごとに抽出する方法。
まず、記事テーブル抽出部分をサブクエリとして作成する。

$articles = Article::select(
    'a.member_id',
    DB::raw('MAX(a.public_date) as max_public_date')  // メンバーごとに記事の最新の日付
)
->from('articles as a')
->where('a.is_public', '=', 1)  // 公開中の記事
->groupBy('a.member_id');

メンバー抽出部分を作成し、サブクエリ部分を結合させる。

$members = Member::select(
    'm.id',
    'a.max_public_date'
)
->from('members as m')
->joinSub($articles, 'a', function($join){    // artilesテーブルサブクエリを結合
    $join->on('m.id', '=', 'a.member_id');    // サブクエリのメンバーidと紐付け
})
->get();

外部結合の場合は、join()をleftJoin()、または、rightJoin()にすればOK。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です