添加包含模型的多个计数字段以在 cakephp 3 中查询
Add multiple count fields of contained model to query in cakephp 3
我想在我的模型中,而不是另一个模型包含的完整模型条目集,只是它们的数量。我可以通过将“大小”字段添加到结果集中来做到这一点,但我想在查询中这样做,因为我想对结果进行动态分页和排序。我正在使用这段代码,但由于某种原因,如果第一个计数不为零,则两个计数字段具有相同的值,即第二个计数字段的值。
$query = $this->Users->find('all')
->contain(['Likes','Favs']);
$query
->select(['like_count' => $query->func()->count('Likes.id')])
->leftJoinWith('Likes')
->group(['Users.id'])
->autoFields(true);
$query
->select(['fav_count' => $query->func()->count('Favs.id')])
->leftJoinWith('Favs')
->group(['Users.id'])
->autoFields(true);
$this->paginate['sortWhitelist'] = [
'name',
'email',
'last_login',
'fav_count',
'like_count',
];
我想知道为什么会发生这种情况,如果有任何其他方法可以做我尝试的事情,那就是 ('name', email, 'last_login',喜欢用户的id,Favs条目的数量与用户的id)。我试过用join()做left join,但是没能得到我想要的结果
如果你有多个join,那么你需要用DISTINCT
来计算,例如:
COUNT(DISTINCT Likes.id)
这是因为您的结果将包含 Likes * Favs
行数,对于每个加入的点赞,所有收藏都将加入,即对于 2
点赞和 10
点赞,您d 总共有 20
行。常规 COUNT()
将包括这些行中的每一行。
另请注意,您不需要重复所有分组等操作,并且可以使用 select()
的可调用对象来避免破坏构建器。
$query = $this->Users
->find('all')
->select(function (\Cake\ORM\Query $query) {
return [
'like_count' => $query->func()->count(
$query->func()->distinct(['Likes.id' => 'identifier'])
),
'fav_count' => $query->func()->count(
$query->func()->distinct(['Favs.id' => 'identifier'])
),
];
})
->autoFields(true)
->contain(['Likes', 'Favs'])
->leftJoinWith('Likes')
->leftJoinWith('Favs')
->group(['Users.id']);
使用函数生成器生成 DISTINCT
是一种解决方法,因为还没有 API 可以专门生成关键字。结果将类似于 DISTINCT(Likes.id)
,但它可以正常工作,括号将被解释为关键字后表达式的一部分,而不是函数调用的一部分。
我想在我的模型中,而不是另一个模型包含的完整模型条目集,只是它们的数量。我可以通过将“大小”字段添加到结果集中来做到这一点,但我想在查询中这样做,因为我想对结果进行动态分页和排序。我正在使用这段代码,但由于某种原因,如果第一个计数不为零,则两个计数字段具有相同的值,即第二个计数字段的值。
$query = $this->Users->find('all')
->contain(['Likes','Favs']);
$query
->select(['like_count' => $query->func()->count('Likes.id')])
->leftJoinWith('Likes')
->group(['Users.id'])
->autoFields(true);
$query
->select(['fav_count' => $query->func()->count('Favs.id')])
->leftJoinWith('Favs')
->group(['Users.id'])
->autoFields(true);
$this->paginate['sortWhitelist'] = [
'name',
'email',
'last_login',
'fav_count',
'like_count',
];
我想知道为什么会发生这种情况,如果有任何其他方法可以做我尝试的事情,那就是 ('name', email, 'last_login',喜欢用户的id,Favs条目的数量与用户的id)。我试过用join()做left join,但是没能得到我想要的结果
如果你有多个join,那么你需要用DISTINCT
来计算,例如:
COUNT(DISTINCT Likes.id)
这是因为您的结果将包含 Likes * Favs
行数,对于每个加入的点赞,所有收藏都将加入,即对于 2
点赞和 10
点赞,您d 总共有 20
行。常规 COUNT()
将包括这些行中的每一行。
另请注意,您不需要重复所有分组等操作,并且可以使用 select()
的可调用对象来避免破坏构建器。
$query = $this->Users
->find('all')
->select(function (\Cake\ORM\Query $query) {
return [
'like_count' => $query->func()->count(
$query->func()->distinct(['Likes.id' => 'identifier'])
),
'fav_count' => $query->func()->count(
$query->func()->distinct(['Favs.id' => 'identifier'])
),
];
})
->autoFields(true)
->contain(['Likes', 'Favs'])
->leftJoinWith('Likes')
->leftJoinWith('Favs')
->group(['Users.id']);
使用函数生成器生成 DISTINCT
是一种解决方法,因为还没有 API 可以专门生成关键字。结果将类似于 DISTINCT(Likes.id)
,但它可以正常工作,括号将被解释为关键字后表达式的一部分,而不是函数调用的一部分。