如何在 laravel 中的查询中应用减法?

How to apply subtraction in the query in laravel?

我有一个包含所有记录的数组。我将所有这些记录传递给一个循环,在那里我得到了空列的总和。

这部分工作正常,现在我的要求是我想再添加一项基于多一列的检查 refund

如果任何列包含 refund=1 应从总数中减去该金额,请您帮助我实现该方案

foreach ($row_data as $key => $value) {
    $data_arr[$key]['total'] = ['Price'=> $value->whereIn('clear', null)->sum('amount')];
}

数据

data = [
    {'amount' => 55, 'clear' => 'null', 'refund' => '0'},
    {'amount' => 5,  'clear' => 'null', 'refund' => '1'},
    {'amount' => 10, 'clear' => 'null', 'refund' => '0'},
];

预期结果是:-60

实际结果是:- 70

我没有你所有的代码都有变量声明,所以我用你的用例创建了逻辑片段。

编辑:您可以简单地获取总金额并减去总退款,如下面的代码所示

/** @var Collection $data */
$data = collect([
  ['amount' => 55, 'clear' => null, 'refund' => false],
  ['amount' => 5, 'clear' => null, 'refund' => true],
  ['amount' => 10, 'clear' => null, 'refund' => false],
]);

$totalAmount = $data->whereNull('clear')->sum('amount');

$totalRefund = $data->whereNull('clear')
  ->where('refund', true)
  ->sum('amount'); // = 5

$subValue = $totalAmount - $totalRefund

reduce 应该有帮助。

$data = [
    ['amount' => 55, 'clear' => null, 'refund' => '0'],
    ['amount' => 5,  'clear' => null, 'refund' => '1'],
    ['amount' => 10, 'clear' => null, 'refund' => '0'],
];

你可以很露骨

// sum if refund is 0, substract if refund is 1
$sum = collect($data)
    ->where('clear', null)
    ->reduce(function ($carry, $item) {
        if ($item['refund'] == '0') {
            return $carry + $item['amount'];
        } elseif ($item['refund'] == '1') {
            return $carry - $item['amount'];
        }
    }, 0);

或者写短一点

// sum if refund is 0, substract otherwise
$sum = collect($data)
    ->where('clear', null)
    ->reduce(fn($carry, $item) => ($item['refund'] == '0')
        ? $carry + $item['amount']
        : $carry - $item['amount']);

您甚至可以使用 php 的 array_reduce and array_filter 函数在没有集合的情况下完成此操作。工作方式几乎相同。

$sum = array_reduce(
    array_filter($data, function ($item) {
        return $item['clear'] == null;
    }),
    function($carry, $item) {
        return $item['refund'] == '0'
            ? $carry + $item['amount']
            : $carry - $item['amount'];
});
$sum = array_reduce(
    array_filter($data, fn($item) => $item['clear'] == null)
    fn($carry, $item) => $item['refund'] == '0'
        ? $carry + $item['amount']
        : $carry - $item['amount']
);