将SQL查询转换为CakePHP 3.0

时间:2015-09-11 16:16:01

标签: mysql sql cakephp cakephp-3.0 query-builder

查询如下

select T.username,
sum(T.size) as totSize,
count(*) total,
count(case when T.type = 'facebook' then 1 else null end) as facebook,
count(case when T.type = 'instagram' then 1 else null end) as instagram,
count(case when T.type = 'device' then 1 else null end) as device
from (SELECT users.username, pictures.size, pictures.type from users left join pictures on pictures.user_id = users.id) as T 
group by T.username

与每个'用户'相关联,有几个'图片'。 基本上,我想要做的是:

  1. 左连接用户和图片表
  2. 按类型计算图片
  3. 总结图片尺寸
  4. 按用户分组
  5. SQL查询在应用于数据库时有效,但我需要在CakePHP 3.0应用程序中表示它。 我设法使用模型关联LEFT JOIN表。在UsersTable中:

    $this->hasMany('Pictures', [
    'foreignKey' => 'user_id',
    'joinType' => 'LEFT'
    ]);
    

    然后在我的find方法中:

    $options['contain'] = ['Pictures' => function ($q) {
    return $q
    ->select(['user_id', 'size', 'type']);}];
    $options['fields'] = array('Users.username');
    $query = $this->find('all', $options);
    

    如何继续查询?如果我尝试访问包含的数据(与'Pictures.type'一样),我返回SQL错误,指出该列不在字段列表中。 我觉得这可能是错误的做法,但我想不出其他方法。

    提前致谢!

1 个答案:

答案 0 :(得分:0)

<强>解决

var fs = require('fs')
var fe = ""
var cb;
module.exports = function(filePath, fileExtention, callback){
  fe = fileExtention
  cb = callback;
  fs.readdir(filePath, findFiles)
}

var findFiles = function (err, list){
  if(err) return cb("Something went wrong", null) 
  var fileArray = []
  list.forEach(function(file){
    if(file.indexOf('.' + fe) > -1) fileArray.push(file)
  })
  return cb(null, fileArray)
}

这允许选择连接的字段为

$options['contain'] = array('Users');
$query = $this->Pictures->find('all', $options);
$query->select(['Users.username', 'Users.plan', 'Users.id']);
$query->select(['sum' => $query->func()->sum('size'),])
      ->select(['count' => $query->func()->count('*'),])
      ->select(['facebook' => $query->func()
          ->count('case when type = \'facebook\' then 1 else null end'),])
      ->select(['instagram' => $query->func()
          ->count('case when type = \'instagram\' then 1 else null end'),])
      ->select(['device' => $query->func()
           ->count('case when type = \'device\' then 1 else null end'),])
      ->group('user_id');

return $query;