如何将在左连接中具有连接的 sql 转换为查询构建器?

Posted

技术标签:

【中文标题】如何将在左连接中具有连接的 sql 转换为查询构建器?【英文标题】:How to convert a sql which has a join within a left join to query builder? 【发布时间】:2019-12-21 14:49:40 【问题描述】:

我需要从 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)

(问题)这是我尝试从上面的 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();

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

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

并生成 SQL

SQL:从v_dts中选择v_dts.*左连接(in_h内连接in_d2in_h.doc_code=in_d2.doc_codein_h.@987654 = in_d2.bookin_h.doc_code = IN)

谁能帮我找出我的问题? 谢谢。

【问题讨论】:

这看起来像 Perl,但您使用的是什么查询生成器?除了调用get,你可以让它打印它生成的SQL吗? 这是来自 php Laravel 的查询构建器。生成的 SQL 显示在错误消息SQL: select v_dts.* from v_dts left join (in_h inner join in_d2 on in_h.doc_code = in_d2.doc_code and in_h.book = in_d2.book and in_h.doc_code = IN) 【参考方案1】:

您需要一个子查询左连接。 ->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');

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

$order_progress = DB::table('v_dts')
    ->select('v_dts.*')
    ->leftJoinSub($ref_books, 'i',function($join)
        $join->on('v_dts.book', '=', 'i.ref_book');
    )
    ->get();

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

见"Sub-Query Joins" in the Laravel docs。

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

【讨论】:

感谢您的耐心解释。这对我来说是正确的答案。

以上是关于如何将在左连接中具有连接的 sql 转换为查询构建器?的主要内容,如果未能解决你的问题,请参考以下文章

将具有许多连接的复杂 SQL 查询转换为 Eloquent

SQL Server:在左连接查询的执行计划中插入隐藏的“排序”

如何将带有内连接语句的 Sql 查询转换为带有 Where 语句的 sql 查询(语句中没有内连接)

如何将带有内连接的 sql 查询转换为 linq lambda 表达式?

如何将左连接横向 SQL 查询转换为 Laravel Eloquent 查询?

左连接 SQL 查询 - MS Access