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

Laravel Eloquent按HasMany关联分组:按职位聚合用户ID

Laravel Eloquent按职位分组用户ID的实现方案

嘿,刚好我之前处理过类似需求,给你两种Laravel Eloquent的实现方式,都能精准输出你想要的键值对格式:

方法一:直接从UserPosition模型查询(性能更优)

这种方式不需要加载完整的User模型实例,仅操作关联表,查询效率更高,推荐优先使用:

use Illuminate\Support\Facades\DB;
use App\Models\UserPosition;

$groupedPositions = UserPosition::query()
    ->select('position', DB::raw('GROUP_CONCAT(user_id SEPARATOR ",") as user_ids'))
    ->groupBy('position')
    ->get()
    ->mapWithKeys(function ($entry) {
        return [$entry->position => explode(',', $entry->user_ids)];
    });

逻辑说明:

  1. 用GROUP_CONCAT聚合函数,把同一职位下的所有user_id拼接成逗号分隔的字符串;
  2. 通过mapWithKeys集合方法,将查询结果转换为「职位名 => 用户ID数组」的结构。

方法二:通过User模型关联查询

如果你的业务场景需要同时用到User模型的其他字段,可以从用户端发起查询:

use App\Models\User;

$groupedPositions = User::with('positions')
    ->get()
    // 把每个用户的职位拆分为独立的「职位-用户ID」条目
    ->flatMap(function ($user) {
        return $user->positions->map(function ($position) use ($user) {
            return [
                'position' => $position->position,
                'user_id' => $user->id
            ];
        });
    })
    // 按职位名称分组
    ->groupBy('position')
    // 提取每组的用户ID并转为数组
    ->map(function ($group) {
        return $group->pluck('user_id')->toArray();
    });

逻辑说明:

  1. 先预加载所有用户的职位关联数据(避免N+1查询);
  2. 用flatMap将嵌套的职位数据展开为一维集合;
  3. 按职位分组后,提取每组的用户ID并转换为数组。

两种方法最终都会输出你需要的格式:

[ 
    'Developer' => [1, 9],
    'Designer' => [2],
    'Teacher' => [1],
    'Singer' => [3, 10],
    'Architect' => [3],
    'Accountant' => [4, 11],
    'Baker' => [2],
    'Actress' => [7],
    'Chef' => [11],
    'Butcher' => [10, 8],
    'Carpenter' => [8, 7, 1] 
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:27:33