【问题标题】:BelongsToMany relation. How to get unique rowsBelongsToMany 关系。如何获取唯一行
【发布时间】:2019-04-11 13:18:18
【问题描述】:

我在 DB 中有下一个 'member_companies' 表:

并且在模型中的成员有一个关系:

public function companies()
{
    return $this->belongsToMany(Company::class, 'member_companies');
}

它还给我所有有重复的公司。比如Member::find(238)->companies->pluck('id')返回

[
  6,
  5,
  7,
  2,
  10,
  8,
  4,
  13,
  14,
  10,
  8,
  13
]

但我只想要独特的物品。喜欢

[
    6,
    5,
    7,
    2,
    10,
    8,
    4,
    13,
    14,
]   

我怎样才能用雄辩的关系做到这一点?

【问题讨论】:

  • 关系是否还应该获取其他数据透视列,例如branch_id
  • 没有。它不应该。

标签: laravel eloquent unique has-and-belongs-to-many


【解决方案1】:

不确定它是否是新添加的,但你可以这样做(至少在 Laravel 7 中):

public function companies()
{
    return $this->belongsToMany(Company::class, 'member_companies')->distinct();
}

【讨论】:

  • 它在我的情况下完美运行:return $this->belongsToMany(AnimatedObject::class, 'animated_object_pose', 'category_id', 'object_id')->distinct();
  • 这仅在您不包含数据透视表中的任何列时才有效,即您不能使用->withPivot()->withTimestamps()
  • @miker MySQL(可能还有其他数据库引擎)不允许选择不在“DISTINCT”或“GROUP BY”子句中的列,因为存在多行(因此有多个值)对于返回的每个不同集的这些列。查看 MySQL 的 ONLY_FULL_GROUP_BY 配置以获取更多信息。
【解决方案2】:

您应该在控制器中使用unique() 方法:

Member::find(238)->companies->pluck('id')->unique('id');

文档:

unique 方法返回集合中的所有唯一项。返回的集合保留原始数组键

在处理嵌套数组或对象时,可以指定用于确定唯一性的键

或者在你的关系中你可以使用groupBy():

public function companies()
{
    return $this->belongsToMany(Company::class, 'member_companies')->groupBy('id');
}

【讨论】:

  • 是的。但这是通过集合的方式。通过这种方式,我从 DB 接收到不需要的信息。但是当我从数据库请求数据时,我想过滤数据。这一定是某种关系
  • 你也可以在你的关系中使用这个方法,这样你就不需要在你的控制器中过滤了。
  • 我不能。我收到下一个错误:调用未定义的方法 Illuminate\Database\Eloquent\Relations\BelongsToMany::unique()
  • 我的错误,尝试使用 groupBy,我更新了我的答案。
  • 我不能。我收到下一个错误:语法错误或访问冲突:1055 Expression #85 of SELECT list is not in GROUP BY 子句并且包含非聚合列 ...
【解决方案3】:

我找到了下一个解决方案:

public function companies()
{
    $relation = $this->belongsToMany(Company::class, 'member_companies');

    $relation->getQuery()->getQuery()
        ->joins[0]->table = \DB::raw('(SELECT DISTINCT member_id, company_id FROM member_companies) as member_companies');

    return $relation;
}

但也许这段代码有更微妙的变体?

【讨论】:

    【解决方案4】:

    你可以像这样使用 group by

    Member::with(['companies' => function($query){
        $query->groupBy('id');
    }])->get();
    

    【讨论】:

    • 请写出我如何在这种关系中使用它: public function Companies() { return $this->belongsToMany(Company::class, 'member_companies'); }
    • 您可以通过这种方式在关系上应用 groupby orderby 和不同条件,在调用公司功能时,您可以定义哪些数据以及您希望从该关系中获得什么数据。
    • 我必须在 config/database.php 中设置 strict => false。这不是很好的解决方案
    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多