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

Laravel 8中如何使用Eloquent实现左连接?关联查询分组异常问题

问题排查

1. 关联关系定义错误

你写反了两个模型的关联逻辑:

  • 父表CommonUnit对应多个子表Item记录,应该定义hasMany关联,而非belongsTo
  • belongsTo是子模型用来关联父模型的方法,第二个参数是子模型里的外键字段名
    你的外键逻辑也搞反了:子表Item才会存储父表的外键id_common_unit(你代码里的item_id_common_unit应该就是这个字段)

2. 预加载with()无法实现SQL层面的左连接分组

with()是Laravel的预加载机制,本质是执行两次独立查询:

  1. 先查CommonUnit表的所有符合条件的记录
  2. 再用第一步拿到的id_common_unit集合去查Item表,最后在PHP层面把关联数据匹配到父结果上
    你在主表查询上加的groupBy只会作用于第一次的CommonUnit查询,完全不会影响关联的Item数据的分组逻辑,自然达不到你要的连表分组效果。

修正方案

第一步:修正关联定义

修改CommonUnit.php的关联方法:

public function items()
{
    // 第一个参数:子模型类,第二个参数:子表的外键字段,第三个参数:父表的主键字段
    return $this->hasMany(\App\Item::class, 'item_id_common_unit', 'id_common_unit');
}

如果你的Item表存储父表外键的字段是id_common_unit,把第二个参数改成id_common_unit即可。

第二步:选择适合的查询方式

方案A:保留预加载,直接在PHP层面处理分组

如果不需要SQL层面连表,只是要按id_common_unit聚合关联的Item数据,直接去掉主查询的groupBy即可,预加载会自动把对应Item匹配到每个CommonUnit下:

$masterCommonUnit = CommonUnit::select('id_common_unit', 'name_unit', 'information_unit', 'created_by', 'edited_by')
    ->with(['items' => function ($query) {
        $query->select('id_item', 'item_id_common_unit');
    }])
    ->orderBy($order, $dir)
    ->get()
    ->toArray();

返回的结果里每个CommonUnit条目下都会有items字段,存储所有关联的Item子记录,天然按父表id分组。

方案B:SQL层面左连接分组查询

如果确实需要在SQL层面执行左连接连表后分组,直接用leftJoin方法:

$masterCommonUnit = CommonUnit::select(
        'common_units.id_common_unit',
        'common_units.name_unit',
        'common_units.information_unit',
        'common_units.created_by',
        'common_units.edited_by',
        // 按需聚合Item字段,比如统计每个CommonUnit关联的Item数量
        \DB::raw('COUNT(items.id_item) as item_count'),
        \DB::raw('GROUP_CONCAT(items.id_item) as item_ids')
    )
    ->leftJoin('items', 'common_units.id_common_unit', '=', 'items.item_id_common_unit')
    ->orderBy($order, $dir)
    ->groupBy('common_units.id_common_unit')
    ->get()
    ->toArray();

注意:如果开启了MySQL的ONLY_FULL_GROUP_BY模式,select里所有非聚合的字段都必须出现在groupBy里,上述写法默认id_common_unit是common_units的主键,所以可以只按这个字段分组。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:36:01