在HATBM表上使用WHERE和COUNT的CakePHP GROUP BY

时间:2012-11-26 12:03:34

标签: cakephp count group-by has-and-belongs-to-many cakephp-2.2

虽然我知道group上的containfieldsorderfind()选项,但我似乎无法做出以下建议使用CakePHP 2.2.3进行查询:

SELECT `User`.*, SUM(`Influence`.`id`) AS matches
FROM `db`.`users` AS `User` 
    LEFT JOIN `db`.`influences_users` AS `InfluencesUser` ON (`User`.`id` = `InfluencesUser`.`user_id`) 
    LEFT JOIN `db`.`influences` AS `Influence` ON (`InfluencesUser`.`influence_id` = `Influence`.`id`)
WHERE 1 = 1
AND `Influence`.`id` IN (1, 2, 3, 4)
GROUP BY `User`.`id` 
ORDER BY COUNT(`Influence`.`id`) DESC

基本上,我正在尝试检索具有Users 1,2,3和4的Influences数组,COUNT()表上有Influences函数,然后按COUNT() DESC订购。

在CakePHP中是否有一种干净的方式(我宁愿不使用任何黑客或函数,如Model::query())?


编辑: 它实际上不是SUM()而是COUNT(),但我没有改变任何问题。

3 个答案:

答案 0 :(得分:4)

您可以使用

仅为下一个查询动态添加虚拟字段
$this->virtualFields['matches'] = 'SUM(Influence.id)';

然后直接在结果数组中使用它:

echo $user['User']['matches']; // if you query on the User model that is

您也可以在订单/条件等上使用它:

'order' => array('User__matches' => 'DESC')

你需要处理模型,其他所有模型都是“belongsTo”! 因此使用“InfluencesUser”并包含“Influence”和“User”

所以在你的情况下:

$this->User->InfluencesUser->virtualFields['matches'] = 'SUM(Influence.id)';
...
$results = $this->User->InfluencesUser->find(...)

echo $result['InfluencesUser']['matches']; //in the view

'order' => array('InfluencesUser__matches' => 'DESC')

答案 1 :(得分:2)

我设法找到了一个解决方案,不是太苛刻,除非有人有更好的解决方案(当你看到我得到的答案数量时不是很多),这里是:

$this->User->virtualFields['matches'] = 'COUNT(InfluencesUser.influence_id)';
$matches = $this->User->find(
        'all',
        array(
            'joins' => array(
                array(
                    'alias' => 'InfluencesUser',
                    'table' => 'influences_users',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'InfluencesUser.influence_id' => $userInfluences, //$userInfluences contains the list of influences I want to do the restriction on
                        '`InfluencesUser`.`user_id` = `User`.`id`'
                    )
                )
            ),
            'group' => 'User.id',
            'order' => array('User__matches' => 'DESC'),
        ));


我手动加入InfluencesUser表(我实际上并不需要Influence表,只有influence_id列表)来制作一个大表。我只需要在influence_id表格上执行限制(join),然后我可以执行goup bycount()并附加count()字段我的结果数组,感谢mark's answer

显然我会更喜欢使用像contain参数这样的东西,但似乎不允许我在这种特殊情况下用join做我能做到的事情。

希望这可以节省一些时间。

答案 2 :(得分:0)

子查询怎么样?

http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#sub-queries

answered a question使用此方法处理HATBM问题。这是复杂查询的有用方法。