mysql - CakePHP模型查询-复杂-多表-求和-计数-分组依据

标签 mysql cakephp database-design model

大家好,节日快乐。

最近我的任务是将一个 beta 应用程序从纯 PHP/jQuery 转换为 CakePHP/ExtJS(我是新手)。

我的问题是填充主网格的最复杂的查询。

为了简单起见,有 3 个表具有正确的烘焙关系和模型:ProjectsToDoExtraToDo

Projects hasMany ToDoExtraToDo

ToDoExtraToDo 有列 TitleComplete

我的目标是根据这三个表获得每个项目的完成百分比。 我采用的方法是 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/

相关文章:

php - 从 CakePHP 中获取具有特定索引的 mysql 记录

java - JPA:外键注释

php - ERD图设计问题

php - 在模式而不是新页面中加载查询搜索结果

python - 使用peewee连接mysql时得到 “TypeError: Connect() got multiple values for keyword argument ' db'”

mysql - CakePHP中基于MySQL函数查找

php - CakePHP 3 - 使用 LocalStringFormat 解析日期以更正 SQL 格式和更正验证

mysql - 数据库设计 - 上下文约束

mysql - Azure:如何最好地将 SQL 数据库与 MySQL/Web 服务连接

mysql - 将facebook数据存储到mysql