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

Yii2中能否通过多层hasMany关联获取唯一Acquisitor对象?

问题描述

现有如下模型关联关系:

  1. Order模型关联多个Product模型,关联方法定义:
public function getProducts() {
    return $this->hasMany(Product::class, ['id' => 'id_product']);
}
  1. Product模型关联多个Acquisitor模型,关联方法定义:
public function getAcquisitors() {
    return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor']);
}

现在有两个疑问:

  • 能否在Order模型中编写关联方法,返回包含唯一Acquisitor实例的ActiveQuery?
  • 若在Order中编写如下关联方法,是否会返回重复的Acquisitor实例?能否实现去重?
public function getAcquisitors() {
    return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor'])->via('products');
}
解答
  • 直接使用->via('products')的这个关联方法会返回重复的Acquisitor实例。原因很简单:如果同一个Acquisitor关联了多个Product,且这些Product都属于同一个Order,关联查询时会因为多表关联的逻辑,把同一个Acquisitor重复返回多次。
  • 当然可以实现去重,有两种常用方案:
    1. 调用distinct()方法:在关联链中添加distinct(),让SQL自动过滤重复记录。修改后的代码如下:
      public function getAcquisitors() {
          return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor'])
              ->via('products')
              ->distinct();
      }
      
      这个操作会在生成的SQL语句中加入DISTINCT关键字,直接去掉重复的Acquisitor记录。
    2. 使用groupBy()分组:根据Acquisitor的主键字段进行分组,也能达到去重效果。假设Acquisitor表的主键是id,代码可以写成:
      public function getAcquisitors() {
          return $this->hasMany(Acquisitor::class, ['id' => 'id_acquisitor'])
              ->via('products')
              ->groupBy('acquisitor.id');
      }
      
      注意要替换成你实际项目中Acquisitor表的主键字段名,避免出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:17:38