问题描述
我有一个称为存款的字段,我正在尝试创建一个称为余额的虚拟字段。在我期望的输出之下,就像链接总和。
deposit balance
100 100
300 400
10 410
我尝试了下面实体中的代码
public $balance = 0;
protected function _getBalance()
{
$this->balance = $this->balance + $this->deposit;
return $this->balance;
}
我所有的0
都已结清余额。
我得到如下结果
deposit balance
100 0
300 0
10 0
我如何获得期望的结果?
解决方法
一个实体对其他实体一无所知,但这是必须的,以便它能够汇总余额。
我想到的两个解决方案是:a)遍历所有结果并修改数据,或者b)如果您的DBMS支持它们,则使用窗口函数在SQL级别上创建运行总计。
如果要遍历所有结果,则可以访问前一个结果的余额并计算总和,并相应地填充renameat2(AT_FDCWD,"dir1","dir2",RENAME_EXCHANGE);
字段,例如在结果格式化程序中:
balance
在SQL级别上,窗口函数可让您汇总以前的行:
$query->formatResults(function (\Cake\Collection\CollectionInterface $results) {
$previous = null;
return $results->map(function ($row) use (&$previous) {
if ($previous === null) {
$row['balance'] = $row['deposit'];
} else {
$row['balance'] = $previous['balance'] + $row['deposit'];
}
$previous = $row;
return $row;
});
});
这将创建一个$query->select(function (\Cake\ORM\Query $query) {
return [
'deposit','balance' => $query
->func()
->sum('deposit')
->over()
->order('id')
->rows(null)
];
});
子句,如下所示:
SELECT
其中,总和是在直到当前行(包括当前行)的所有先前行中计算的。
应注意,自CakePHP 4.1起,仅支持构建器上的窗口函数,在先前版本中,您必须创建自定义表达式或传递原始SQL:
SELECT
deposit,(
SUM(deposit) OVER (
ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)
) AS balance
另请参见