Laravel中如何从重复列表中获取每个商家的独立客户
获取Laravel商家的唯一客户列表
针对你的场景,商家(role=pharma)和买家(role=user)的关联链是商家User → Product → Order → 买家User,直接用hasManyThrough会因同一买家多次下单产生重复数据,下面提供几种高效去重的实现方案:
方案一:使用whereHas关联查询(推荐,支持链式操作)
在User模型中定义customers关联方法,通过子查询筛选出购买过当前商家产品的唯一买家:
// app/Models/User.php public function customers() { return User::customer() // 调用查询作用域,仅筛选买家角色 ->whereHas('orders.product', function ($query) { $query->where('products.user_id', $this->id); }) ->distinct(); } // 可选:添加查询作用域快速区分角色 public function scopeMerchant($query) { return $query->where('role', 'pharma'); } public function scopeCustomer($query) { return $query->where('role', 'user'); }
使用方式:
// 获取ID为1的商家及其唯一客户列表 $merchant = User::merchant()->find(1); $uniqueCustomers = $merchant->customers;
方案二:通过关联集合去重(适合小数据量)
如果不需要后续链式查询,可以直接通过集合操作去重:
// app/Models/User.php public function customers() { return $this->hasMany(Product::class) ->with('orders.user') ->get() ->pluck('orders.*.user') // 提取所有订单关联的买家 ->flatten() // 多维集合转一维 ->unique('id'); // 按用户ID去重 }
方案三:原生Join查询
直接用SQL Join实现,性能更优:
// app/Models/User.php public function customers() { return User::customer() ->select('users.*') ->join('orders', 'orders.user_id', '=', 'users.id') ->join('products', 'products.id', '=', 'orders.product_id') ->where('products.user_id', $this->id) ->distinct(); }
关键前置配置
确保关联模型的关系定义正确:
// app/Models/Product.php public function orders() { return $this->hasMany(Order::class); } // app/Models/Order.php public function user() { return $this->belongsTo(User::class); }
内容的提问来源于stack exchange,提问作者Francis Annor
相关产品推荐
相关产品推荐

