我使用此代码进行简单的分页:
$paginate = array(
'limit' => 30,
'fields' => array('DISTINCT Doctor.id','Doctor.*'),
'order' => array('Doctor.id' => 'desc'),
'joins' => array(
array('table' => 'doctors_medical_degrees',
'alias' => 'DoctorsMedicalDegree',
'type' => 'INNER',
'conditions' => array(
'Doctor.id = DoctorsMedicalDegree.doctor_id',
)
),
),
'recursive' => -1,
);
$this->Paginator->settings = $paginate;
$data = $this->Paginator->paginate('Doctor');
现在的问题是我正在使用Inner join所以对于Distinct结果我正在使用Distinct Doctor.id,但是在查询分页时的cakephp计数查询不包括Distinct Doctor.id
'query' => 'SELECT COUNT(*) AS `count` FROM `pharma`.`doctors` AS `Doctor` INNER JOIN `pharma`.`doctors_medical_degrees` AS `DoctorsMedicalDegree` ON (`Doctor`.`id` = `DoctorsMedicalDegree`.`doctor_id`)'
你可以看到否
COUNT(DISTINCT Doctor.id)
所以分页会返回更多可以实际返回的结果
答案 0 :(得分:2)
问题在于,分页符没有将字段传递给find('count')
调用,因此默认情况下它始终依赖于*
。
但即使它会传递字段,传递一个数组会使find('count')
调用期望将要计数的字段作为COUNT()
表达式传递,即类似
'fields' => array('COUNT(DISTINCT Doctor.id) as `count`')
然而,无论如何这对于paginator都无效,所以您需要的是自定义find('count')
来电。
有关详细信息,请参阅 Cookbook > Pagination > Custom Query Pagination 。
自定义查询分页可能是您最好的选择,这完全取决于您如何进行计数。
例如,你可以使用paginator组件传递的额外值,这样你就可以传递字段来指望find('count')`调用,就像这样(未经测试的示例代码):< / p>
class Doctor extends AppModel {
// ...
public function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
$parameters = compact('conditions');
if($recursive != $this->recursive) {
$parameters['recursive'] = $recursive;
}
if(!empty($extra['countField'])) {
$parameters['fields'] = $extra['countField'];
unset($extra['countField']);
}
return $this->find('count', array_merge($parameters, $extra));
}
}
$this->Paginator->settings = array(
'limit' => 30,
'fields' => array('DISTINCT Doctor.id','Doctor.*'),
// ...
'countField' => 'DISTINCT Doctor.id'
);
$data = $this->Paginator->paginate('Doctor');
然后应该创建一个看起来像
的COUNT
查询
SELECT COUNT(DISTINCT Doctor.id) AS `count` ...
答案 1 :(得分:0)
我在CakePHP - Pagination total count differs from actual count when using DISTINCT找到了解决方案 在模型中添加公共函数paginateCount,并在分页器中使用distinct选项,如:
$this->paginate = array('limit' => $limit, 'order' => array('Item.created' => 'ASC', 'Item.code' => 'ASC'),
'fields' => 'DISTINCT Item.*',
'conditions' => $conditions,
'countField' => array('Item.id'),
'joins' => $joins,
'distinct' => 'Item.id',
'contain' => array(
'Image' => array('limit' => 1),
'ItemsTag'
)
);