Laravel 计算具有条件的两列之和
Laravel calculate sum of two columns with a condition
我有从数据库中获取的这个仓库集合
[
{
"id": 1,
"warehouse": "India"
"sales": [
{
"id": 1,
"warehouse_id": 1,
"price": "120.00",
"quantity": 1000,
"status": 1
},
{
"id": 2,
"warehouse_id": 1,
"price": "20.00",
"quantity": 100,
"status": 1
},
{
"id": 3,
"warehouse_id": 1,
"price": "40.00",
"quantity": 1000,
"status": 2
}
]
},
{
"id": 2,
"warehouse": "Malaysia"
"sales": [
{
"id": 4,
"warehouse_id": 2,
"price": "160.00",
"quantity": 100,
"status": 1
}
]
}
]
我要计算每个仓库的总收入
总收入是根据销售status
属性计算的
如果状态 = 1,则产品已交付,因此应将 price * quantity
添加到总收入中
如果 status = 2,产品被退回,所以它应该从总收入中减去 price * quantity
印度仓库的基本示例:
total_income = 120*1000 + 20*100 - 40*1000
马来西亚:
total_income = 160*100
我试过使用 Warehouse::withSum();
,但没有任何效果。
我想知道是否有处理集合的好方法
老实说,我会走下面的路线:
显然,如果您不使用完整的数字(如您的示例),我的解决方案将不得不稍作修改。 if/else 也可以扩大,如果你有超过 2 个状态。
$total_income = 0;
foreach($warehouses as $warehouse)
{
foreach($warehouse->sales as $sale)
{
if($sale->status = 1)
{
$total_income += ($sale->price * $sale->quantity);
}else{
$total_income -= ($sale->price * $sale->quantity);
}
}
}
这是我将如何做的粗略示例。似乎每个 'warehouse' 都有不同的位置。印度对马来西亚。我的示例更多地是关于总计,但您始终可以将每个不同仓库的结果保存在不同的变量中,或者作为数组中的 key/value 对(我会这样做)。
您可以将一些回调传递给集合的 sum()
方法:
$warehouses_collection->map(function ($warehouse) {
return (object) [
'id' => $warehouse->id,
'warehouse' => $warehouse->warehouse,
'total_income' => collect($warehouse->sales)->sum(function ($sale) {
((int) $sale->price) * $sale->quantity * ($sale->status == 1 ? 1 : -1)
})
];
});
WithSum
在这里使用有点棘手,但调用 withAggregate
可以。
Warehouse::withAggregate(
'sales as total_income',
'sum(case when status = 1 then price * quantity when status = 2 then price * quantity * -1 else 0 end)'
)->get()
我有从数据库中获取的这个仓库集合
[
{
"id": 1,
"warehouse": "India"
"sales": [
{
"id": 1,
"warehouse_id": 1,
"price": "120.00",
"quantity": 1000,
"status": 1
},
{
"id": 2,
"warehouse_id": 1,
"price": "20.00",
"quantity": 100,
"status": 1
},
{
"id": 3,
"warehouse_id": 1,
"price": "40.00",
"quantity": 1000,
"status": 2
}
]
},
{
"id": 2,
"warehouse": "Malaysia"
"sales": [
{
"id": 4,
"warehouse_id": 2,
"price": "160.00",
"quantity": 100,
"status": 1
}
]
}
]
我要计算每个仓库的总收入
总收入是根据销售status
属性计算的
如果状态 = 1,则产品已交付,因此应将 price * quantity
添加到总收入中
如果 status = 2,产品被退回,所以它应该从总收入中减去 price * quantity
印度仓库的基本示例:
total_income = 120*1000 + 20*100 - 40*1000
马来西亚:
total_income = 160*100
我试过使用 Warehouse::withSum();
,但没有任何效果。
我想知道是否有处理集合的好方法
老实说,我会走下面的路线:
显然,如果您不使用完整的数字(如您的示例),我的解决方案将不得不稍作修改。 if/else 也可以扩大,如果你有超过 2 个状态。
$total_income = 0;
foreach($warehouses as $warehouse)
{
foreach($warehouse->sales as $sale)
{
if($sale->status = 1)
{
$total_income += ($sale->price * $sale->quantity);
}else{
$total_income -= ($sale->price * $sale->quantity);
}
}
}
这是我将如何做的粗略示例。似乎每个 'warehouse' 都有不同的位置。印度对马来西亚。我的示例更多地是关于总计,但您始终可以将每个不同仓库的结果保存在不同的变量中,或者作为数组中的 key/value 对(我会这样做)。
您可以将一些回调传递给集合的 sum()
方法:
$warehouses_collection->map(function ($warehouse) {
return (object) [
'id' => $warehouse->id,
'warehouse' => $warehouse->warehouse,
'total_income' => collect($warehouse->sales)->sum(function ($sale) {
((int) $sale->price) * $sale->quantity * ($sale->status == 1 ? 1 : -1)
})
];
});
WithSum
在这里使用有点棘手,但调用 withAggregate
可以。
Warehouse::withAggregate(
'sales as total_income',
'sum(case when status = 1 then price * quantity when status = 2 then price * quantity * -1 else 0 end)'
)->get()