Yii模型findAll()和count()返回不同数量的结果

时间:2014-03-23 23:16:20

标签: yii

更新:请参阅问题的结尾

我正在与Yii合作(特别是RESTFullYii,但我怀疑这与问题有关)

模型有一个CDbCriteria:

        $criteria = new CDbCriteria(
                array(
                        'together' => true,
                        'with' => array(
                            'roles'=> array(
                                'having' => "roles.role IN ($userRoles)"
                                ))
                    )
            );
        $count = $model->count($criteria);
        $result= $model->findAll($criteria);

虽然findAll()方法只返回3条记录(这很好),但count()方法返回13,这是由$model

我在MySQL中启用了查询日志记录,我发现Yii生成的两个查询完全不同

SELECT `t`.`id` AS `t0_c0`,
       `t`.`name` AS `t0_c1`,
       `t`.`description` AS `t0_c2`,
       `t`.`enabled` AS `t0_c3`,
       `t`.`issuegroup_id` AS `t0_c4`,
       `t`.`role_id_exec` AS `t0_c5`,
       `t`.`require_attachment` AS `t0_c6`,
       `roles`.`id` AS `t1_c0`,
       `roles`.`role` AS `t1_c1`,
       `roles`.`enabled` AS `t1_c2`,
       `roles`.`description` AS `t1_c3`
FROM `issuetype` `t`
       LEFT OUTER JOIN `role_has_issuetype` `roles_roles` ON
         (`t`.`id`=`roles_roles`.`issuetype_id`)
       LEFT OUTER JOIN `role` `roles` ON
         (`roles`.`id`=`roles_roles`.`role_id`)
HAVING (roles.role IN ('user'))
LIMIT 100

另一个问题:

SELECT COUNT(DISTINCT `t`.`id`)
FROM `issuetype` `t`
LEFT OUTER JOIN `role_has_issuetype` `roles_roles` ON
    (`t`.`id`=`roles_roles`.`issuetype_id`)
LEFT OUTER JOIN `role` `roles` ON
    (`roles`.`id`=`roles_roles`.`role_id`)

这是findAll()count()方法的正常行为,还是我做了一些我不应该做的事情,或者这是Yii中的错误?

如何正确获取记录的实际数量?

count($model->findAll($criteria))似乎工作正常,但这是正确的解决方案还是只是一种解决方法?

(从性能角度来看,我认为它可能比实际count()更好,因为我运行了两次相同的查询,这是MySQL服务器缓存的)

更新: 我在GitHub上问了同样的问题,保罗克里莫夫亲切地指出,'have'和'group'条款没有必要在联合表中,并且将它移出'with'是完全可以的。它在这里:https://github.com/yiisoft/yii/issues/3297

2 个答案:

答案 0 :(得分:1)

使用Having中的count方法时,Yii在使用ActiveRecord条件时遇到了一些问题,但在较新的Yii版本中修复了https://github.com/yiisoft/yii/pull/2167

答案 1 :(得分:0)

您需要在应用count()或findAll()方法之前克隆模型:

$result= $model->findAll($criteria);
$modelClone = clone $model;
$count = $model->count($criteria);