我正在构建一个cake3应用程序,它在表double_measures中收集了大量的时间序列数据:
select * from double_measures limit 20;
+----+--------------------+---------------------+-------+--------+
| id | physical_sensor_id | time | milis | value |
+----+--------------------+---------------------+-------+--------+
| 1 | 1 | 2016-11-25 00:50:01 | 0 | 306.15 |
| 2 | 2 | 2016-11-25 00:50:01 | 0 | 300.15 |
| 3 | 3 | 2016-11-25 00:50:01 | 0 | 308.15 |
| 4 | 4 | 2016-11-25 00:50:01 | 0 | 308.15 |
| 5 | 6 | 2016-11-25 00:50:01 | 0 | 310.15 |
| 6 | 7 | 2016-11-25 00:50:01 | 0 | 310.15 |
| 7 | 8 | 2016-11-25 00:50:01 | 0 | 305.15 |
| 8 | 9 | 2016-11-25 00:50:01 | 0 | 306.15 |
| 9 | 10 | 2016-11-25 00:50:01 | 0 | 304.15 |
| 10 | 11 | 2016-11-25 00:50:01 | 0 | 309.15 |
| 11 | 1 | 2016-11-25 00:55:01 | 0 | 306.15 |
| 12 | 2 | 2016-11-25 00:55:01 | 0 | 300.15 |
| 13 | 3 | 2016-11-25 00:55:01 | 0 | 308.15 |
| 14 | 4 | 2016-11-25 00:55:01 | 0 | 308.15 |
| 15 | 6 | 2016-11-25 00:55:01 | 0 | 310.15 |
| 16 | 7 | 2016-11-25 00:55:01 | 0 | 310.15 |
| 17 | 8 | 2016-11-25 00:55:01 | 0 | 305.15 |
| 18 | 9 | 2016-11-25 00:55:01 | 0 | 306.15 |
| 19 | 10 | 2016-11-25 00:55:01 | 0 | 304.15 |
| 20 | 11 | 2016-11-25 00:55:01 | 0 | 309.15 |
+----+--------------------+---------------------+-------+--------+
目前我正在通过以下查询$measures = $table->find('all',['order'=>['id'=>'DESC']])->select(['time','milis','value'])->where(['physical_sensor_id'=>$sid])->limit($limit);
选择值,该查询返回给定传感器的最后$ limit条目。
但是,我更愿意均匀地重新对表格进行重新采样以得到每个第n个值,其中n为
[$ sid的值] / $ limit。
感谢How do you select every n-th row from mysql,我知道如何在MySql中执行此操作,但是有没有办法在Cakephp3中完成此操作?
当然,我可以在查询后重新进行采样,但这不是一个选项,因为我的内存用于巨大的结果集。
答案 0 :(得分:0)
找到解决方案:
在我的AppController中我定义了一个函数如下:
protected function initRowNumbering(){
$conn = ConnectionManager::get('default');
$conn->execute("SET @i = 0");
}
然后在我需要重新采样的控制器中,我有以下内容:
$query = $table->find('all',['order'=>['id'=>'DESC']])->select(['time','milis','value'])->where(['physical_sensor_id'=>$sid]);
if ($sample != null){ // if the number of samples is set:
$this->initRowNumbering(); // add index variable
$count = $query->count(); // count total number of values for given sensor
$step = (int)($count / $sample); // calculate sample step size
if ($step > 0){
$measures = $query->where(['(@i := @i+1)%'.$step.'=0']); // add resampling filter
} else {
$measures = $query;
}
} else {
$measures = $query->limit($limit);
}
这很好用,虽然它可能不是最优雅的解决方案。
有任何改进意见吗?