大家好,节日快乐。
最近我的任务是将一个 beta 应用程序从纯 PHP/jQuery 转换为 CakePHP/ExtJS(我是新手)。
我的问题是填充主网格的最复杂的查询。
为了简单起见,有 3 个表具有正确的烘焙关系和模型:Projects
、ToDo
、ExtraToDo
Projects
hasMany ToDo
和 ExtraToDo
。
ToDo
和 ExtraToDo
有列 Title
和 Complete
。
我的目标是根据这三个表获得每个项目的完成百分比。
我采用的方法是 Complete
列的 SUM 除以 Complete
列的 COUNT .我正在尝试以 CakePHP 的方式来提高可读性/性能/otherstuffIdontknowyet。
最初,在原始 SQL 中我是这样做的:
SELECT
`idProject`,
(SELECT
ROUND((SUM(`Complete`) / COUNT(`Complete`)) * 100),
FROM
(SELECT `Complete`, `ProjectID` FROM `ToDo`
UNION ALL
SELECT `Complete`, `ProjectID` FROM `ExtraToDo`) orders
WHERE
`ProjectID` = `idProject`
) AS 'Completion'
FROM
`Projects`
我还很容易地在 Kohana PHP MVC 框架中使用它,我在决定使用 CakePHP 之前尝试过。我喜欢他们的查询是如何创建的......:
private function get_completion() {
$Query = DB::select('ProjectID', array(DB::expr('ROUND((SUM(`Complete`) / COUNT(`Complete`)) * 100)'), 'Completion'))
->from(array('ToDo', 'ExtraToDo'))
->group_by('ProjectID');
return $Query;
}
public function get_all() {
$Query = DB::select()
->from('Projects')
->join(array(self::get_completion(), 'Completion'))
->on('projects.id', '=', 'Completion.ProjectID')
->execute()
->as_array();
return $Query;
}
不幸的是,在以 CakePHP 方式执行此操作时,我一直在努力使它在 CakePHP 中工作。
我漂亮确定 virtualFields 是我回答的关键,但在阅读文档并尝试 x、y 和 z 之后。我一直无法理解它们以及它们之间的关系。
提前谢谢你 -T6
最佳答案
那是很多嵌套选择。 IMO 你最好构建一个更好的查询。
这应该让你继续。
class Project extends AppModel {
public $findMethods = array(
'completion' => true
);
// other code
protected function _findCompletion($state, $query, $results = array()) {
if ($state == 'before') {
$this->virtualFields['total'] = 'ROUND((SUM(Todo.Complete + TodoExtra.Complete) / (COUNT(Todo.Complete) + COUNT(TodoExtra.Complete))) * 100)';
$query['fields'] = array(
$this->alias . '.' . $this->primaryKey,
'total'
);
$query['joins'] = array(
array(
'table' => 'todos',
'alias' => 'Todo',
'type' => 'left',
'foreignKey' => false,
'conditions'=> array('Todo.project_id = ' , $this->alias . '.' . $this->primaryKey)
),
array(
'table' => 'todo_extras',
'alias' => 'TodoExtra',
'type' => 'left',
'foreignKey' => false,
'conditions'=> array('TodoExtra.project_id = ' . $this->alias . '.' . $this->primaryKey)
),
);
$query['group'] = array(
$this->alias . '.' . $this->primaryKey
);
return $query;
}
return $results;
}
// other code
}
现在您有一个自定义查找方法,可以像 find('first')
或 find('all')
一样使用。
来自 Controller :
$this->Project->find('completion');
或者在Project模型中
$this->find('completion');
它应该返回这样的东西:
$results = array(
0 => array(
'Project' => array(
'id' => 1,
'total' => 50
)
),
1 => array(
'Project' => array(
'id' => 2,
'total' => 75
)
)
);
关于mysql - CakePHP模型查询-复杂-多表-求和-计数-分组依据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14115967/