首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过计数关联数据CakePHP 3筛选查询

通过计数关联数据CakePHP 3筛选查询
EN

Stack Overflow用户
提问于 2020-05-31 18:20:59
回答 1查看 390关注 0票数 0

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

我知道下一个代码是错误的,但是它应该是这样的:

代码语言:javascript
复制
$articles = $this->Articles->find();

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-31 18:55:50

首先了解如何在原始SQL中执行该操作总是很有帮助的,这将使您更容易理解如何使用CakePHP的查询生成器来复制它。

例如,不能在WHERE子句中使用聚合,这在所有受支持的DBMS中都是禁止的。在应用分组之前(即在计算任何内容之前),必须先检查WHERE子句中的聚合,而后者是在分组后计算的。

通常,您会在SQL中执行类似的操作:

代码语言:javascript
复制
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

使用这样的查询生成器可以很容易地实现这一点:

代码语言:javascript
复制
$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表中的可索引列进行比较(即您可以这样做):

代码语言:javascript
复制
$query = $this->Articles
    ->find()
    ->where([
        'Articles.comment_count >=' => 2,
    ]);

另请参阅

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62120632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档