在 CakePHP ORM 中使用计数子查询

Using count subquery within CakePHP ORM

我正在查看 CakePHP 文档,但我看不到任何解释如何在 MySQL 语句中执行子查询的地方。我基本上想计算每个用户作为一个字段的积分数,但目前它正在将所有用户的积分累计计入一个字段:

   $this->Users->find()
       ->contain(['Plans','Products'])
       ->contain('Credits', function ($q) {
           return $q->select(['count' => $q->func()->count('*')]);
       })->group(['Users.id']);

我尝试创建的查询更像是:

SELECT *, (SELECT COUNT(*) FROM credits Credits WHERE Credits.user_id = Users.id) as credit_count FROM users Users group by Users.id ASC

包含的 hasMany 关联将始终在单独的查询中检索,这就是应用您在包含回调中定义的条件的位置(检查 Sql [= 的日志选项卡14=]).

要获得您正在寻找的结果,需要加入关联,并计算同一查询中的 Credits,如下所示:

$this->Users
    ->find()
    ->select(function(\Cake\ORM\Query $q) {
        return ['count' => $q->func()->count('Credits.id')]
    })
    ->select($this->Users)
    ->contain(['Plans','Products'])
    ->leftJoinWith('Credits')
    ->group(['Users.id']);

或显式使用子查询,其工作方式是简单地创建一个常规查询对象,并将其传递到查询构建器接受表达式对象的任何地方,例如作为 select 列表中的值:

$subquery = $this->Users->Credits
    ->find()
    ->select(function(\Cake\ORM\Query $q) {
        return ['count' => $q->func()->count('Credits.id')]
    })
    ->where(function (\Cake\Database\Expression\QueryExpression $exp) {
        return $exp->equalFields('Credits.user_id', 'Users.id'):
    });

$this->Users
    ->find()
    ->select(['count' => $subquery])
    ->select($this->Users)
    ->contain(['Plans','Products']);

另见