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

如何在Laravel中按Zip分组并关联查询对应买家列表?

解决方案

你的代码存在两个核心问题:

  1. 关联关系定义错误:BuyerZip与Buyer是一对一的从属关系,一条buyer_zips记录对应一个买家,应该用belongsTo而非hasMany;
  2. 分组字段错误:表中不存在zip_id字段,且直接按zip分组无法直接关联到完整的买家列表。

以下是两种可行的解决方式:

方式一:Eloquent集合处理(代码简洁易维护)

1. 修正模型关联

在BuyerZip.php中修正关联关系:

public function buyer()
{
    return $this->belongsTo(Buyer::class, 'buyer_id');
}

2. 查询并整理数据

通过预加载买家、分组、去重得到目标格式:

$zipBuyers = BuyerZip::with('buyer')
    ->get()
    ->groupBy('zip')
    ->map(function ($group) {
        return [
            'zip' => $group->first()->zip,
            'buyers' => $group->pluck('buyer')->unique('id')->values()->toArray()
        ];
    })
    ->values()
    ->toJson();
  • groupBy('zip'):按邮编分组所有关联记录
  • unique('id'):避免同一买家在同一邮编下重复出现(应对buyer_zips中可能的重复组合)
  • values():重置数组索引,保证结果结构整洁

方式二:原生SQL聚合(大数据量场景更高效)

如果数据量较大,集合处理性能不足,可直接在数据库层面完成分组聚合:

$results = DB::table('buyer_zips')
    ->select(
        'zip',
        DB::raw('GROUP_CONCAT(DISTINCT CONCAT(b.id, "|", b.name) SEPARATOR ";") as buyers')
    )
    ->join('buyers as b', 'buyer_zips.buyer_id', '=', 'b.id')
    ->groupBy('zip')
    ->get()
    ->map(function ($item) {
        $buyers = collect(explode(';', $item->buyers))->map(function ($buyerStr) {
            list($id, $name) = explode('|', $buyerStr);
            return ['id' => (int)$id, 'name' => $name];
        });
        return [
            'zip' => $item->zip,
            'buyers' => $buyers->toArray()
        ];
    })
    ->toJson();

这种方式通过GROUP_CONCAT聚合买家信息,再解析成目标格式,数据库层面处理效率更高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:54:16