【问题标题】:Laravel nested join queries with query builderLaravel 使用查询生成器进行嵌套连接查询
【发布时间】:2016-11-16 19:25:37
【问题描述】:

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

我通过 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 不再有权访问 join 方法?

原始 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

【问题讨论】:

    标签: php mysql laravel join query-builder


    【解决方案1】:

    方式1.你可以用builder写部分查询:

        $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');
    

    【讨论】:

    • 展示复杂连接的好例子,在 laravel 5.7 中仍然可以完美运行
    猜你喜欢
    • 2015-11-17
    • 2018-06-02
    • 2016-02-05
    • 2021-01-01
    • 2020-03-12
    • 2015-05-09
    • 2022-01-20
    • 2013-05-30
    • 2017-05-26
    相关资源
    最近更新 更多