【发布时间】:2014-03-23 23:16:20
【问题描述】:
更新:见问题的结尾
我正在使用 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 上问过同样的问题,Paul Klimov 亲切地指出,“have”和“group”子句没有必要出现在连接表中,完全可以将其移出“with”参见它在这里:https://github.com/yiisoft/yii/issues/3297
【问题讨论】:
-
我不能说为什么值不同,但我一直使用 count($result) 没有问题。这种用法完全没问题。
-
@crafter 感谢您的输入,至少我知道我用这种方法是安全的 :)
-
count($result) 的问题是,如果你有分页,那么 count 将只有分页条目的数量。在您的示例中,由于对请求应用了限制,因此计数最多为 100。
-
根据示例代码,您可以使用 WHERE 而不是 HAVING,我认为这可以解决问题。但正如其他人所提到的,你可能最好升级到最新版本的 Yii。另外,请记住 Yii2 非常接近它的 beta 版本。
标签: yii