You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询转换为Laravel Eloquent查询失败求助

把MySQL查询转换为Laravel Eloquent写法

我来帮你把这段MySQL查询转换成Laravel Eloquent的实现,完全对齐原查询的逻辑,一步步来:

首先,假设你的模型命名遵循Laravel规范(CompositeInventory对应composite_inventories表,CompositeHasInventory对应composite_has_inventories表,Inventory对应inventories表),下面是具体实现:

1. 模型关联(可选但推荐)

先在CompositeInventory模型里定义和中间表的关联,方便后续复用:

// app/Models/CompositeInventory.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class CompositeInventory extends Model
{
    protected $table = 'composite_inventories';

    public function compositeHasInventories()
    {
        return $this->hasMany(CompositeHasInventory::class, 'composite_inventory_id');
    }
}

2. 核心Eloquent查询实现

这段代码完全还原你原SQL的逻辑:

use App\Models\CompositeInventory;
use Illuminate\Support\Facades\DB;

$results = CompositeInventory::select(
        'composite_inventories.id',
        'composite_inventories.purchase_item_name',
        'composite_inventories.sales_item_name',
        'composite_has_inventories.type',
        DB::raw('GROUP_CONCAT(p.itemcode) AS purchase_items'),
        DB::raw('GROUP_CONCAT(s.itemcode) AS sales_items')
    )
    // 左连中间表
    ->leftJoin('composite_has_inventories', 'composite_inventories.id', '=', 'composite_has_inventories.composite_inventory_id')
    // 左连sale类型的库存表(带连接条件)
    ->leftJoin('inventories as s', function ($join) {
        $join->on('composite_has_inventories.inventory_id', '=', 's.id')
             ->where('composite_has_inventories.type', '=', 'sale');
    })
    // 左连purchase类型的库存表(带连接条件)
    ->leftJoin('inventories as p', function ($join) {
        $join->on('composite_has_inventories.inventory_id', '=', 'p.id')
             ->where('composite_has_inventories.type', '=', 'purchase');
    })
    // 按非聚合字段分组(MySQL严格模式要求)
    ->groupBy(
        'composite_inventories.id',
        'composite_inventories.purchase_item_name',
        'composite_inventories.sales_item_name',
        'composite_has_inventories.type'
    )
    ->get();

关键细节解释:

  • 对于GROUP_CONCAT这类原生聚合函数,必须用DB::raw()包裹——因为Eloquent的select方法默认会转义字段名,无法直接识别原生SQL函数。
  • 原SQL中带条件的左连接(比如us.type='sale'),通过闭包形式的leftJoin实现,确保连接逻辑和原SQL完全一致。
  • groupBy必须包含所有非聚合字段,这是MySQL严格SQL模式下的强制要求,和你原查询的分组逻辑保持统一。

如果你的原SQL还有后续的WHERE或HAVING条件,直接在查询链末尾追加->where()或->having()即可。

内容的提问来源于stack exchange,提问作者Code Embassy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:17:16