如何将在左联接内具有联接的SQL转换为查询生成器?

Wei*_*ang 5 php sql join query-builder laravel

我需要从sql中编写查询构建器,该查询构建器在左联接内具有联接。

这是在另一个左联接内具有联接的SQL。

select v_dts.* from v_dts 
left join(select in_d2.ref_book from in_h
inner join in_d2 on(in_h.doc_code=in_d2.doc_code and in_h.book=in_d2.book) 
where in_h.doc_code='IN' group by in_d2.ref_book) as i
on(v_dts.book=i.ref_book)
Run Code Online (Sandbox Code Playgroud)

(问题)这是我尝试从上面的SQL转换的查询生成器。

$order_progress = DB::table('v_dts')
->select('v_dts.*')
->leftJoin('in_h',function($join_in_h){
   $join_in_h->select('in_d2.ref_book');
      $join_in_h->join('in_d2',function($join_in_d2){
      $join_in_d2->on('in_h.doc_code','=','in_d2.doc_code');
      $join_in_d2->on('in_h.book','=','in_d2.book');
      $join_in_d2->where('in_h.doc_code','=','IN');
      $join_in_d2->groupBy('in_d2.ref_book');
   });
})
->get();
Run Code Online (Sandbox Code Playgroud)

但是,我的查询生成器是错误的。它显示一条错误消息

SQLSTATE [42000]:语法错误或访问冲突:1064 SQL语法有错误;查看与您的MySQL服务器版本相对应的手册以获取正确的语法

并生成SQL

SQL:从左联接中选择v_dts。* v_dts(。= 。和。= 。以及。= IN 上的in_h内部联接)in_d2in_hdoc_codein_d2doc_codein_hbookin_d2bookin_hdoc_code

任何人都可以帮助我解决我的问题吗?谢谢。

Sch*_*ern 4

您需要一个子查询左连接。->leftJoin('in_h',function($join_in_h){...}不进行子查询连接;这是一个带有奇特连接子句的常规左连接。

而是使用->leftJoinSub.

您可以使用 joinSub、leftJoinSub 和 rightJoinSub 方法将查询连接到子查询。这些方法中的每一个都接收三个参数:子查询、其表别名和定义相关列的闭包。

编写子查询。

$ref_books = DB::table('in_h')
    ->select('in_d2.ref_book')
    ->join('in_d2', function($join){
        $join->on('in_h.doc_code','=','in_d2.doc_code')
             ->where('in_h.book','=','in_d2.book');
    })
    ->where('in_h.doc_code','=','IN')
    ->groupBy('in_d2.ref_book');
Run Code Online (Sandbox Code Playgroud)

并在另一个查询中使用它。

$order_progress = DB::table('v_dts')
    ->select('v_dts.*')
    ->leftJoinSub($ref_books, 'i',function($join){
        $join->on('v_dts.book', '=', 'i.ref_book');
    })
    ->get();
Run Code Online (Sandbox Code Playgroud)

您可以使用->dd()->dump()转储生成的 SQL 以进行调试。

请参阅Laravel 文档中的“子查询连接”

注意:我没有 Laravel,所以我无法检查这是否 100% 正确,但它应该能让你走上正确的道路。