使用 Laravel Query Builder 进行复杂的 MySQL 内连接查询

Posted

技术标签:

【中文标题】使用 Laravel Query Builder 进行复杂的 MySQL 内连接查询【英文标题】:Complex MySQL inner join query with Laravel Query Builder 【发布时间】:2019-05-19 22:28:21 【问题描述】:

我正在尝试使用 Laravel 查询生成器运行此查询。 我认为查询是正确的,因为当我在 MySQL Workbench 中运行查询时,查询会执行并得到预期的结果。我知道我们可以使用 laravel 查询生成器编写原始查询,但它对 SQL 是开放的注入漏洞。所以我试图在没有原始查询的情况下继续前进。

这是查询

SELECT invoice.InvNo,customer.RouteCode,customer.CustomerCode,rootplan_product.RouteplanCode,invoice.Status 
FROM rootplan_product
INNER JOIN 
customer ON customer.RouteCode = rootplan_product.RouteCode
AND
customer.CustomerCode = rootplan_product.customercode
INNER JOIN
invoice ON invoice.CustomerCode = customer.CustomerCode 
WHERE
rootplan_product.RouteCode='MO-A' AND invoice.Status IN ('PENDING','ACTIVE') 
ORDER BY invoice.Status desc

我已将每个表设为模型并像这样在控制器中使用。由于表名与命名约定不同。我在每个模型中都添加了protected $table = 'correct_table_name';

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use \App\Route;
use \App\Customer;
use \App\Invoice;
use \App\Rootplan_Product;

这是控制器功能

public function retrieveRouteCodeData(Request $request)
    try 
        $RouteCode = $request->RouteCode;
        $retrievedData = DB::table('rootplan_product')
                    ->join('customer', function($join)
                        $join->on('customer.RouteCode', '=', 'rootplan_product.RouteCode');
                        $join->on(DB::raw('(customer.CustomerCode = rootplan_product.CustomerCode)'));
                    )
                    ->join('invoice', 'invoice.CustomerCode', '=', 'customer.CustomerCode')
                    ->select('invoice.InvNo', 'customer.RouteCode', 'customer.CustomerCode', 'rootplan_product.RouteplanCode', 'invoice.Status')
                    ->where('rootplan_product.RouteCode', $RouteCode)
                    ->orderBy('invoice.Status','desc')
                    ->get();
                    return response()->json(['msg'=>'Updated Successfully', 'result'=>$retrievedData, 'success'=>true]);
      
      catch (\Exception $e) 
          return response()->json(['msg'=>$e->getMessage()]);

      



在控制台中我收到此错误

“SQLSTATE[42S22]: 未找到列: 1054 'on 子句'中的未知列'' (SQL: 选择invoice.InvNo, customer.RouteCode, customer.CustomerCode , rootplan_product.RouteplanCode, invoice.Status from rootplan_product 内连接 customer customer.RouteCode = rootplan_product.RouteCode 和 (customer.CustomCodeer rootproduct. ) = `` 在invoice.CustomerCode 上的内部连接invoice = customer.CustomerCode 其中rootplan_product.RouteCode = MO-A order by invoice.Status desc)"

我了解查询很复杂,如果有任何帮助,我们将不胜感激!

【问题讨论】:

对我来说,您的 DB::raw 连接似乎引起了问题,您是否尝试像上面的连接一样进行操作? @SplittyDev 是的。我试过了,但我无法弄清楚查询中带有 AND 部分的内部连接。所以我尝试了这种方式 我相信你可以做到以下几点:$join->on('customer.RouteCode', '=', 'rootplan_product.RouteCode')->where('customer.CustomerCode', '=', 'rootplan_product.CustomerCode'); 【参考方案1】:

问题在于 DB::raw 语句。请使用以下内容:

DB::table('rootplan_product')->join('customer', function ($join) 
    $join->on('customer.RouteCode', '=', 'rootplan_product.RouteCode');
    $join->on('customer.CustomerCode', 'rootplan_product.CustomerCode');
)->join('invoice', 'invoice.CustomerCode', '=', 'customer.CustomerCode')
    ->select('invoice.InvNo', 'customer.RouteCode', 'customer.CustomerCode', 'rootplan_product.RouteplanCode', 'invoice.Status')
    ->where('rootplan_product.RouteCode', '123')
    ->whereIn('invoice.Status', ['PENDING','ACTIVE'])
    ->orderBy('invoice.Status', 'desc')
    ->get();

这将生成以下 SQL:

SELECT `invoice`.`InvNo`,
       `customer`.`RouteCode`,
       `customer`.`CustomerCode`,
       `rootplan_product`.`RouteplanCode`,
       `invoice`.`Status`
FROM `test`
INNER JOIN `customer` ON `customer`.`RouteCode` = `rootplan_product`.`RouteCode`
AND `customer`.`CustomerCode` = `rootplan_product`.`CustomerCode`
INNER JOIN `invoice` ON `invoice`.`CustomerCode` = `customer`.`CustomerCode`
WHERE `rootplan_product`.`RouteCode` = ?
  AND `invoice`.`Status` IN (?, ?)
ORDER BY `invoice`.`Status` DESC

【讨论】:

以上是关于使用 Laravel Query Builder 进行复杂的 MySQL 内连接查询的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:调用未定义的方法 Illuminate\\Database\\Query\\Builder

如何使用 Laravel Eloquent 和 Laravel Query Builder 进行联合查询?

Laravel 查询错误 - 调用未定义的方法 Illuminate\Database\Query\Builder::query()

如何使用 laravel Query Builder 进行复杂查询

使用 SQL Query 或 Laravel SQL Query Builder 创建表/列组合

Laravel中的Query Builder