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

如何用Laravel Eloquent单查询获取按字段分组的关联数组数据

解决Laravel中按字段分组并获取对应所有记录的问题

嗨,我懂你的需求——你想把city表的数据按country字段分组,让每个国家作为关联数组的键,对应的所有城市记录数组作为值,但直接用City::groupBy('country')->get()只返回了每组的第一条记录,对吧?这是因为数据库层面的groupBy是用于聚合统计的,默认只会返回每组的第一条数据,而非你需要的所有关联记录。下面给你两种可行的解决方案:

方法一:利用Laravel集合分组(简单直观)

先查询出所有需要的记录,再用Laravel集合的groupBy方法在内存中分组,这种方式适合数据量不大的场景:

// 先获取指定字段的所有记录,再按country分组
$cities = City::select('name', 'country', 'barcode')
    ->get()
    ->groupBy('country')
    // 将每个分组的模型集合转为目标数组格式
    ->map(fn($group) => $group->map(fn($city) => [$city->name, $city->country, $city->barcode])->toArray())
    ->toArray();

执行后就能得到你期望的格式:

[
    'egypt' => [
        ['cairo', 'egypt', '02'],
        ['alex', 'egypt', '02']
    ],
    'usa' => [
        ['washington', 'usa', '56'],
        ['california', 'usa', '56']
    ]
]

方法二:数据库层面聚合(适合大数据量)

如果你的数据量很大,不想把所有记录加载到内存,可以利用MySQL的JSON_ARRAYAGG函数(需要MySQL 5.7及以上版本),在数据库层面直接聚合生成数组:

$cities = City::selectRaw(
    'country, JSON_ARRAYAGG(JSON_ARRAY(name, country, barcode)) as city_list'
)
->groupBy('country')
->get()
// 将country作为键,city_list作为值提取出来
->pluck('city_list', 'country')
->toArray();

这种方式直接让数据库完成聚合,返回的结果就是你要的纯数组格式,内存占用更低。

小提醒

你代码里的Citry应该是笔误,正确的模型名是City哦;集合分组的方式代码更易读、调试方便,但数据量过大时会占用较多内存;数据库聚合的方式性能更好,但依赖数据库的JSON函数支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:38:03