CakePhp 3 - 如何按SUM在包含结果中排序

时间:2015-08-24 10:42:13

标签: php database cakephp associations cakephp-3.0

我正在开发CakePhp 3项目,我需要按照每个评论的投票顺序对文章进行评论。

型号:

  • 文章
  • ArticlesComments
  • ArticlesCommentsVotes
  • 用户

用户与每个模型相关联。 ArticlesComments有文章ID。 ArticlesCommentsVotes有comment_id和user_id。

我需要什么:

  • 正面评论总数
  • 负面评论总数
  • 按编号排序。正面评论
  • 按负面评论数排序

不知何故,我设法得到道达号。积极和否定的评论,但CakePhp不允许我按评论数量排序。

这是我的问题:

$article = $this->Articles->get($id, [
            'contain' => [
                'Categories',
                'Clusters',
                'Tags',
                'ArticlesSteps',
                'PositiveVotes'    => function ($a){
                    return $a->select(['PositiveVotes.article_id', 'votes' => 'COUNT(*)']);
                },
                'NegativeVotes'    => function ($a){
                    return $a->select(['NegativeVotes.article_id', 'votes' => 'COUNT(*)']);
                },
                'ArticlesComments' => function ($q){
                    return $q->contain([
                        'Users'                 => function ($q){
                            return $q->select(['username']);
                        },
                        'CommentVote'           => function ($q){
                            return $q->select(['vote']);
                        },
                        'CommentsPositiveVotes' => function ($q){
                            return $q->select(['CommentsPositiveVotes.comment_id', 'positive' => 'SUM(vote)'])->group('comment_id');
                        },
                        'CommentsNegativeVotes' => function ($a){
                            return $a->select(['CommentsNegativeVotes.comment_id', 'CommentsNegativeVotes.user_id']);
                        }
                    ]);
                }
            ]
        ]);

感谢任何帮助:)

2 个答案:

答案 0 :(得分:0)

我认为,您无法对查询结果进行排序。但在你的情况下,使用名为“CounterCache”的东西会有意义。

http://book.cakephp.org/3.0/en/orm/behaviors/counter-cache.html

答案 1 :(得分:0)

我找到了解决问题的方法。我需要使用左连接。这是我更新的代码:

       // Search comments
        $comments = $this->ArticlesComments->find()->where([
            'ArticlesComments.article_id' => $articleId,
        ])->contain([
            'CommentVote' => function ($q){
                return $q->select(['vote']);
            },
            'Users'       => function ($q){
                return $q->select(['username']);
            },
        ]);

        // Left Join with ArticlesComments
        $comments
            ->leftJoin(
                ['ArticlesCommentsVotes' => 'articles_comments_votes'],
                ['ArticlesComments.id = ArticlesCommentsVotes.comment_id']
            );


        // Case
        $ratingCases = $comments->newExpr()->addCase([
            $comments->newExpr()->add(['ArticlesCommentsVotes.vote' => '1']),
            $comments->newExpr()->add(['ArticlesCommentsVotes.vote' => '0'])
        ], [1, - 1, 0], ['integer','integer','integer']);

        // Calculate rating and sort
        $comments->select(['rating' => $comments->func()->sum($ratingCases)])
                 ->group('ArticlesCommentsVotes.comment_id')->order($sortBy . ' ' . $sortOrder)->autoFields(true);