按计数关联数据CakePHP 3筛选查询

按计数关联数据CakePHP 3筛选查询,cakephp,query-builder,counting,cakephp-3.x,aggregates,Cakephp,Query Builder,Counting,Cakephp 3.x,Aggregates,我想对“文章”进行查询,但我只想要有两个或更多“评论”的“文章”。因此,我必须计算“注释”,并在where子句中使用计数结果 我知道下一个代码是错误的,但可能是这样的: $articles = $this->Articles->find(); $articles->matching('Comments', function ($q) { $commentsCount = $q->func()->count('Comments.id'); re

我想对“文章”进行查询,但我只想要有两个或更多“评论”的“文章”。因此,我必须计算“注释”,并在where子句中使用计数结果

我知道下一个代码是错误的,但可能是这样的:

$articles = $this->Articles->find();

$articles->matching('Comments', function ($q) {
    $commentsCount = $q->func()->count('Comments.id');   
    return $q->where($commentsCount . ' >= ' => 2);
});

我找不到任何关于这方面的信息。

首先要弄清楚如何在原始SQL中实现这一点总是很有帮助的,这样可以更容易地弄清楚如何使用CakePHP的查询生成器复制它

例如,您不能在
WHERE
子句中使用聚合,这在所有受支持的DBMS中都是禁止的
在应用分组之前(即,在计算任何数据之前)对
进行计算的情况下,您必须检查
HAVING
子句中的聚合,该聚合在分组之后进行计算

通常,您会在SQL中执行以下操作:

选择
文章编号。。。
从…起
文章
左连接
comments ON comments.article_id=Articles.id
分组
物品编号
有
计数(Comments.id)>=2
使用查询生成器可以轻松实现这一点,如下所示:

$query=$this->Articles
->查找()
->leftJoinWith('注释')
->组('Articles.id')
->有(功能)(
\Cake\Database\Expression\QueryExpression$exp,
\蛋糕\ORM\Query$Query
) {
返回$exp->gte(
$query->func()->count('Comments.id'),
2.
“整数”
);
});
这样的查询在大型表上可能非常昂贵,因为它不能使用任何索引,因此需要进行完整的表扫描,即必须检查每一行。一种避免这种情况的方法是使用计数器缓存,它将相关记录的数量存储在源表中,这样您就可以与
Articles
表中的可索引列进行比较,也就是说,您可以简单地执行以下操作:

$query=$this->Articles
->查找()
->在哪里([
“Articles.comment_count>=”=>2,
]);
另见