我想对“文章”进行查询,但我只想要有两个或更多“评论”的“文章”。因此,我必须对“注释”进行计数,并在where子句中使用计数结果。
我知道下一个代码是错误的,但是它应该是这样的:
$articles = $this->Articles->find();
$articles->matching('Comments', function ($q) {
$commentsCount = $q->func()->count('Comments.id');
return $q->where($commentsCount . ' >= ' => 2);
});我找不到这方面的任何信息。
发布于 2020-05-31 18:55:50
首先了解如何在原始SQL中执行该操作总是很有帮助的,这将使您更容易理解如何使用CakePHP的查询生成器来复制它。
例如,不能在WHERE子句中使用聚合,这在所有受支持的DBMS中都是禁止的。在应用分组之前(即在计算任何内容之前),必须先检查WHERE子句中的聚合,而后者是在分组后计算的。
通常,您会在SQL中执行类似的操作:
SELECT
Articles.id, ...
FROM
articles Articles
LEFT JOIN
comments Comments ON Comments.article_id = Articles.id
GROUP BY
Articles.id
HAVING
COUNT(Comments.id) >= 2使用这样的查询生成器可以很容易地实现这一点:
$query = $this->Articles
->find()
->leftJoinWith('Comments')
->group('Articles.id')
->having(function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $query
) {
return $exp->gte(
$query->func()->count('Comments.id'),
2,
'integer'
);
});这样的查询在大型表上可能非常昂贵,因为它不能使用任何索引,因此需要进行完整的表扫描(即必须检查每一行)。避免这种情况的一种方法是使用计数器缓存,它在源表中存储关联记录的数量,这样您就可以与Articles表中的可索引列进行比较(即您可以这样做):
$query = $this->Articles
->find()
->where([
'Articles.comment_count >=' => 2,
]);另请参阅
https://stackoverflow.com/questions/62120632
复制相似问题