Laravel Query Builder:如何单查询按agent_id分组聚合currency?
问题描述
现有如下数据集:
| id | agent_id | currency |
|---|---|---|
| 1 | A0001 | IDR |
| 2 | A0002 | MYR |
| 3 | A0001 | THB |
能否仅使用一次Laravel Query Builder,得到如下格式的结果?
[ [ "agent_id" => "A0001", "currency" => [ "IDR", "THB", ], ], [ "agent_id" => "A0002", "currency" => ["MYR"] ] ]
本质是将同一agent_id下的currency字段值聚合为数组。
解决方案
可以实现,具体写法取决于你使用的数据库类型:
1. MySQL/MariaDB 环境
利用GROUP_CONCAT函数将同一agent_id下的currency拼接为字符串,再通过集合的map方法将字符串转为数组:
use Illuminate\Support\Facades\DB; use App\Models\AgentCurrency; // 替换为你的实际模型 $result = AgentCurrency::select('agent_id', DB::raw('GROUP_CONCAT(currency SEPARATOR ",") as currencies')) ->groupBy('agent_id') ->get() ->map(function ($item) { return [ 'agent_id' => $item->agent_id, 'currency' => explode(',', $item->currencies) ]; }) ->toArray();
2. PostgreSQL 环境
PostgreSQL支持直接生成数组的ARRAY_AGG函数,无需额外转换:
use Illuminate\Support\Facades\DB; use App\Models\AgentCurrency; // 替换为你的实际模型 $result = AgentCurrency::select('agent_id', DB::raw('ARRAY_AGG(currency) as currency')) ->groupBy('agent_id') ->get() ->toArray();
补充说明
- 两种写法都只执行了一次数据库查询(
get()方法触发查询),后续的集合转换在内存中完成,符合「仅使用一次Laravel Query Builder」的要求。 - 若未使用模型,可直接用
DB::table()替代模型调用:
// MySQL示例 $result = DB::table('agent_currencies') // 替换为你的实际表名 ->select('agent_id', DB::raw('GROUP_CONCAT(currency SEPARATOR ",") as currencies')) ->groupBy('agent_id') ->get() ->map(function ($item) { return [ 'agent_id' => $item->agent_id, 'currency' => explode(',', $item->currencies) ]; }) ->toArray();
内容的提问来源于stack exchange,提问作者Wei Kang
相关产品推荐
相关产品推荐

