【问题标题】:Need opinion with relations count需要与关系计数的意见
【发布时间】:2020-01-20 13:41:51
【问题描述】:

我很长时间都在寻找这个问题的解决方案:

假设我们有 2 个表,一个表是 Clients 表,第二个表是 ClientAssignment 表: ClientAssignment 表与 Clients 表相关:

public function assignment()
{
    return $this->hasOne(ClientAssignment::class, 'client_id');
}

现在当我想计算有多少 ClientAssignment 有客户时,我会这样做:

$users =[1,2,3,4 .....]
$userAssignments = array();

foreach ($users as $user) {

    $user_assignments = Client::whereHas('assignment', function ($query) use ($user) {
     $query->where('assigned_id', $user);
    });

     $ua['user_id'] = $user;
     $ua['count'] = $user_assignments->count();
     array_push($userAssignments, $ua);
   }

代码运行良好,但在具有 80k 客户端的相对较小的表上,它的性能和查询执行时间约为 20 + 秒, 我的问题是否可以用另一种方法来做同样的事情,但性能和查询执行时间最低?

【问题讨论】:

  • 第一件事,``` public function assignment() { return $this->hasOne(ClientAssignment::class, 'client_id'); } ``` 这应该是 ``` public function assignment() { return $this->hasMany(ClientAssignment::class, 'client_id'); } ```,
  • 不,这不是一个好方法。我不确定你们的关系。但我更喜欢像 DB::table('assignment')->groupBy('user_id')->wereIn('user_id', [...])->where('client_id', 1)->count 这样的原始查询('id') 东西
  • 第二件事,你不必使用eloquent,你可以运行一行sql,比如``` SELECT , (SELECT COUNT() FROM assignment WHERE assignment.client_id = clients.id) as assignmentCount FROM clients` ```
  • 只需使用一个查询即可解决此问题。
  • 那么assigned_iduser 有多个client_assignmentsclient 有一个client_assignment 呢?

标签: php mysql laravel laravel-5 eloquent


【解决方案1】:

根据你的帖子,我认为

Client --- hasOne ----> ClientAssignment  <----- hasMany ---- User
                    [client_id, assigned_id]

所以User 可以有很多ClientClientAssignment

但是,您的client_idassigned_id 都在client_assignment 表中。所以你不能使用hasManyThrough,这就像一个数据透视表;

幸运的是,您可以直接计算client_id,并将assigned_id 视为user_id,只需使用此数据透视表即可。

查询是这样的(使用distinct(client_id)防止脏记录):

ClientAssignment::whereIn('assigned_id', $users)
                  ->groupBy('assigned_id')
                  ->select('assigned_id AS user_id',
                            DB::raw('COUNT(DISTINCT(client_id)) AS count'))
                  ->get()->toArray();

并添加assigned_id 索引以提高性能。

$table->index('assigned_id');

【讨论】:

  • 谢谢,这非常有用,它在其他地方帮助了我并对其进行了测试,但是如果我之前没有提到过,但我们有查询过滤“链接”与 Client 类,例如:$this->applyFiltering ($user_assignments, $request);并且在 applyFiltering 函数中至少有 50 个与 Client 类相关的过滤器/查询构建器,因此它需要是 Client 类而不是 ClientAssignment
  • 例如,'end' col 指的是 Clients 表/类; if ($request->has('end')) { $user_assignments->where('end', 1); }
【解决方案2】:

使用count()


Client::first()->assignments->count();

// Or

Client::find(ID)->assignments()->count();

// or ...


【讨论】:

    猜你喜欢
    • 2011-11-10
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多