2016-07-14 110 views
5

这是一个搜索函数,它返回每个成员注册的最近一年。使用查询生成器的Laravel嵌套连接查询

我知道它与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'); 
    } 
); 

产生的错误是:

调用未定义的方法照亮\数据库\ 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 

回答

2

方式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');