You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何计算已交付订单的平均配送时间?

解决Laravel中计算已交付订单平均配送时间的问题

嘿,我明白你现在卡在哪了——你之前的代码逻辑完全走偏了,直接对updated_at字段求平均得到的是日期本身的平均值,不是配送时长的平均值,这就是为啥会出现那串奇怪的数字,还导致Carbon解析失败的原因。

错误原因拆解

Order::where('status', '=', '8')->avg('updated_at') 干的事儿是把所有已交付订单的updated_at日期转成数据库底层的数值(比如MySQL会把datetime转成20240520123045这类数字),然后求这些数字的平均值,得到的结果根本不是有效的时间戳/日期,自然没法用Carbon解析成天数。

我们真正要算的是每个订单的配送时长(交付时间 - 订单起始时间)的平均值,而不是日期的平均值。

正确解决方案

根据你的订单数据量,推荐两种实用方法:

方法1:数据库层面计算(高效,适合大量订单)

直接在数据库里计算每个订单的配送时长差值,再求平均值,性能拉满:

假设你的订单有created_at字段(订单创建时间,作为配送的起始时间),不同数据库的函数略有区别:

MySQL版本
$avgDeliveryDays = Order::where('status', 8)
    ->selectRaw('AVG(DATEDIFF(updated_at, created_at)) as avg_days')
    ->value('avg_days');

DATEDIFF函数会直接返回updated_at和created_at之间的天数差,再通过AVG求平均值。

PostgreSQL版本
$avgDeliveryDays = Order::where('status', 8)
    ->selectRaw('AVG(EXTRACT(DAY FROM (updated_at - created_at))) as avg_days')
    ->value('avg_days');
SQLite版本
$avgDeliveryDays = Order::where('status', 8)
    ->selectRaw('AVG(JULIANDAY(updated_at) - JULIANDAY(created_at)) as avg_days')
    ->value('avg_days');

如果你的配送起始时间不是created_at(比如是发货时间shipped_at),把字段替换成对应的就行。

方法2:PHP层面计算(灵活,适合少量订单)

如果需要更灵活的时间精度控制(比如精确到小时/分钟),可以先拉取订单数据,再在PHP里计算:

$orders = Order::where('status', 8)->select('updated_at', 'created_at')->get();

$totalDuration = 0;
$orderCount = $orders->count();

if ($orderCount === 0) {
    $avgDeliveryDays = 0;
} else {
    foreach ($orders as $order) {
        // 计算两个日期的天数差,需要精确到小时就换成diffInHours
        $diff = Carbon::parse($order->updated_at)->diffInDays(Carbon::parse($order->created_at));
        $totalDuration += $diff;
    }
    $avgDeliveryDays = $totalDuration / $orderCount;
}

最后验证

不管用哪种方法,得到的$avgDeliveryDays就是你要的平均配送天数,直接用就行,不用再折腾Carbon解析啦。

内容的提问来源于stack exchange,提问作者Jadasdas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:34:53