Laravel使用查询构建器嵌套连接查询

时间:2016-07-14 02:46:36

标签: php mysql laravel join query-builder

这是一个搜索功能,可以返回每个成员注册的最近一年。

我让它使用DB :: raw()调用。但无法让它与查询构建器一起使用。

工作代码:

$query = DB::table('membership as m');
$query->join(
    DB::raw(
        '(SELECT my.*
        FROM membership_years my
        INNER JOIN (
            SELECT member_id,MAX(membership_year) AS max_my
            FROM membership_years
            GROUP BY member_id
        ) my2
        ON my.member_id = my2.member_id
        AND my.membership_year = my2.max_my
        ) my'
    )
,'m.id','=','my.member_id');

我对查询构建器代码的尝试:

$query = DB::table('membership as m');
$query->join('membership_years as my',
  function($j1){
    $j1->join('membership_years as my2',
      function($j2){
        $j2->where('my.membership_year','=','MAX(my2.membership_year)')
        ->on('my.member_id','=','my2.member_id');
      }
    )->on('m.id','=','my.member_id');
  }
);

产生的错误是:

  

调用未定义的方法Illuminate \ Database \ Query \ JoinClause :: join()

我不确定这是否是因为$j2无法再访问加入方法了?

原始MySQL查询:

SELECT my.membership_year,m.*
FROM membership AS m 
INNER JOIN
    (
        SELECT my1.* 
        FROM membership_years my1 
        INNER JOIN 
        (
            SELECT member_id,MAX(membership_year) AS max_my 
            FROM membership_years 
            GROUP BY member_id
        ) my2
        ON my1.member_id = my2.member_id
        AND my1.membership_year = my2.max_my
    ) my
ON m.id = my.member_id
ORDER BY m.id ASC

1 个答案:

答案 0 :(得分:4)

方法1.您可以使用构建器编写部分查询:

    $query = DB::table('membership as m')
        ->select('my.membership_year', 'm.*')
        ->join(DB::raw('(
            SELECT my1.* 
            FROM membership_years my1 
            INNER JOIN (
                SELECT member_id, MAX(membership_year) AS max_my 
                FROM membership_years 
                GROUP BY member_id
            ) my2
            ON my1.member_id = my2.member_id
            AND my1.membership_year = my2.max_my
        ) my'),
        'm.id', '=', 'my.member_id')
        ->orderBy('m.id');

方式2.您也可以编写子查询并使用toSql()方法:

$sub1 = DB::table('membership_years')
    ->select('member_id', DB::raw('MAX(membership_year) AS max_my'))
    ->groupBy('member_id');

$sub2 = DB::table('membership_years as my1')
    ->select('my1.*')
    ->join(DB::raw('(' . $sub1->toSql() . ') my2'),
            function ($join) {
                $join
                    ->on('my1.member_id', '=', 'my2.member_id')
                    ->on('my1.membership_year', '=', 'my2.max_my');
            });

$query = DB::table('membership as m')
    ->select('my.membership_year', 'm.*')
    ->join(DB::raw('(' . $sub2->toSql() . ') my'), 'm.id', '=', 'my.member_id')
    ->orderBy('m.id');