【问题标题】:Yii model findAll() and count() return different number of resultsYii 模型 findAll() 和 count() 返回不同数量的结果
【发布时间】: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


【解决方案1】:

Yii 在使用来自ActiveRecordcount 方法时遇到了Having 标准的问题,但在较新的Yii 版本中已修复:https://github.com/yiisoft/yii/pull/2167

【讨论】:

  • 我在 CHANGELOG 中使用 1.1.14 我发现“错误 #2201:不能在 CActiveRecord::count() (ivokund) 中使用带有绑定参数的“拥有””,它指的是您已链接的问题...但它似乎仍然无法正常工作。我会在那里开始讨论。感谢您为我指明正确的方向。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    相关资源
    最近更新 更多