在CakePHP ORM中使用count子查询

时间:2019-05-21 14:34:06

标签: mysql sql cakephp orm cakephp-3.0

我正在浏览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

1 个答案:

答案 0 :(得分:1)

将始终在单独的查询中检索包含的hasMany关联,这就是将应用您在包含回调中定义的条件的位置(请检查DebugKit的Sql Log选项卡)。 / p>

要获得所需的结果,需要加入关联,并在同一查询中计算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']);

或显式使用子查询,该子查询的工作原理是简单地创建一个常规查询对象,然后将其传递到查询构建器接受表达式对象的位置,例如作为选择列表中的值:

$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']);

另请参见