Laravel关联对象中带$符号的qty字符串转为整数的实现方法
解决方案
你之前的尝试失败是因为with()预加载是独立的关联查询,主表OpenorderImportTemp的查询阶段并不会关联shipment对应的数据表,所以直接在主查询的DB::raw里引用shipment.qty无法获取到对应字段,自然没法完成求和。以下是3种可行方案:
方案1:在Shipment模型中定义访问器(推荐,全局生效)
该方案属于Laravel最佳实践,定义一次后所有获取qty字段的场景都会自动转换为数值类型,无需修改其他业务代码。
在你的Shipment模型中添加如下代码:
// Laravel 9+ 写法 use Illuminate\Database\Eloquent\Casts\Attribute; protected function qty(): Attribute { return Attribute::make( get: function ($value) { // 移除$符号和千分位逗号后转整数 $cleanValue = str_replace(['$', ','], '', $value); return (int) $cleanValue; } ); } // Laravel 8及更早版本写法 public function getQtyAttribute($value) { $cleanValue = str_replace(['$', ','], '', $value); return (int) $cleanValue; }
添加后你原本的查询代码不需要任何修改,返回的shipment->qty就已经是整数类型,可直接用于求和计算。
方案2:查询后通过集合处理(适合临时单次场景)
如果不想修改模型,仅需要在当前接口处理该字段,可以在拿到查询结果后调用集合的map方法遍历处理:
$openorder_data = OpenorderImportTemp::select('id', 'controlNumber', 'ItemNumber') ->with('shipment:id,Item,ColorCode,qty') ->orderBy('id', 'desc') ->where('ControlNumber', '!=', '0') ->get() ->map(function ($item) { if ($item->shipment) { $cleanQty = str_replace(['$', ','], '', $item->shipment->qty); $item->shipment->qty = (int) $cleanQty; // 可按需把求和值挂到主对象上 $item->qtysum = (int) $cleanQty; } return $item; });
如果需要按controlNumber分组求和,直接调用集合内置方法即可:
$groupedSum = $openorder_data->groupBy('controlNumber') ->map(fn($group) => $group->sum('shipment.qty'));
方案3:SQL层面直接求和(适用于大数据量场景)
如果数据量较大,不想把全量数据查出来再计算,可以把预加载改为join关联,在SQL层处理字段格式后直接求和:
$openorder_data = OpenorderImportTemp::select( 'id', 'controlNumber', 'ItemNumber', DB::raw("SUM(CAST(REPLACE(REPLACE(shipments.qty, '$', ''), ',', '') AS UNSIGNED)) as qtysum") ) ->join('shipments', 'shipments.Item', '=', 'openorder_import_temps.ItemNumber') ->orderBy('id', 'desc') ->where('ControlNumber', '!=', '0') ->groupBy('controlNumber') // 需分组求和时放开该行 ->get();
注意把上述代码中的shipments、openorder_import_temps替换为你实际对应的表名即可。
内容的提问来源于stack exchange,提问作者raza9798
相关产品推荐
相关产品推荐

