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

Laravel中合并相同zone_id行并汇总关联driver_id的查询方案

问题描述

我试过StackOverflow上的多种解决方案,但都没用。我有一张名为driver_zones的表,里面存在多条zone_id相同但driver_id不同的记录,需要合并相同zone_id的行,同时关联对应的所有driver_id,求Laravel查询语句。

表结构(前两行zone_id相同):

driver_idzone_id
sJUfNMZ2nJ6b3ecb1b-c29d-45b2-88b3-dabf5c8b6b62
rz8lpiagH16b3ecb1b-c29d-45b2-88b3-dabf5c8b6b62
qY8ynd7tX55aec1540-b62c-43e3-9182-23a89da610d1

期望结果:

Array(
    [0] => Array
        (
            [zone_id] => 6b3ecb1b-c29d-45b2-88b3-dabf5c8b6b62
            [drivers] => Array
                (
                    [0] => Array
                        (
                            [id] => 2
                            [uuid] => sJUfNMZ2nJ
                        )
                    [1] => Array
                        (
                            [uuid] => rz8lpiagH1
                        )
                )
        )
    [1] => Array
        (
            [zone_id] => 5aec1540-b62c-43e3-9182-23a89da610d1
            [drivers] => Array
                (
                    [0] => Array
                        (
                            [uuid] => qY8ynd7tX5
                        )
                )
        )
)
解决方案

方法一:Eloquent关联(推荐)

如果有Driver和Zone模型,先在Zone模型里定义关联关系:

// app/Models/Zone.php
public function drivers()
{
    return $this->belongsToMany(Driver::class, 'driver_zones', 'zone_id', 'driver_id');
}

之后直接查询并格式化结果:

$zones = Zone::with('drivers:id,uuid')->get()->map(function ($zone) {
    return [
        'zone_id' => $zone->id, // 若Zone表用uuid存ID,就改成$zone->uuid
        'drivers' => $zone->drivers->toArray()
    ];
});

方法二:直接聚合查询

MySQL环境

$result = DB::table('driver_zones')
    ->selectRaw('zone_id, GROUP_CONCAT(driver_id) as driver_ids')
    ->groupBy('zone_id')
    ->get()
    ->map(function ($item) {
        $drivers = explode(',', $item->driver_ids);
        return [
            'zone_id' => $item->zone_id,
            'drivers' => array_map(function ($driverId) {
                // 关联Driver表拿详情,不需要的话直接返回['uuid' => $driverId]
                $driver = Driver::where('uuid', $driverId)->select('id', 'uuid')->first();
                return $driver ? $driver->toArray() : ['uuid' => $driverId];
            }, $drivers)
        ];
    });

PostgreSQL环境

$result = DB::table('driver_zones')
    ->selectRaw('zone_id, json_agg(driver_id) as driver_ids')
    ->groupBy('zone_id')
    ->get()
    ->map(function ($item) {
        return [
            'zone_id' => $item->zone_id,
            'drivers' => array_map(function ($driverId) {
                $driver = Driver::where('uuid', $driverId)->select('id', 'uuid')->first();
                return $driver ? $driver->toArray() : ['uuid' => $driverId];
            }, $item->driver_ids)
        ];
    });

方法三:集合分组处理

先查所有记录,再用Laravel集合分组整理:

$driverZones = DB::table('driver_zones')->get();

$result = $driverZones->groupBy('zone_id')->map(function ($group) {
    return [
        'zone_id' => $group->first()->zone_id,
        'drivers' => $group->map(function ($item) {
            $driver = Driver::where('uuid', $item->driver_id)->select('id', 'uuid')->first();
            return $driver ? $driver->toArray() : ['uuid' => $item->driver_id];
        })->toArray()
    ];
})->values()->toArray();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:51