Laravel按指定时间段统计用户订单及发货量的查询实现
Laravel 按日期范围统计用户订单/发货量的正确Eloquent实现
原有代码的核心问题
whereHas闭包中错误调用->get()和groupBy('created_at'),直接破坏了关联查询的构造逻辑,分组维度也不符合统计需求- 调用
withCount时未给关联添加日期筛选条件,最终统计的是用户所有历史订单/发货量,不是选定时间段内的数据 - 未兼容仅传开始日期、仅传结束日期的场景,空值传入
whereBetween会直接触发SQL错误 orWhereHas未做闭包包裹,后续新增查询条件时会出现逻辑判断混乱
正确实现代码
// 初始化User模型查询构造器 $query = User::query(); if (!empty($from) || !empty($to)) { // 复用日期范围筛选逻辑,避免重复写条件 $dateScope = function ($builder) use ($from, $to) { if (!empty($from) && !empty($to)) { $builder->whereBetween('created_at', [$from, $to]); } elseif (!empty($from)) { $builder->where('created_at', '>=', $from); } elseif (!empty($to)) { $builder->where('created_at', '<=', $to); } }; $query->withCount([ 'orders' => $dateScope, 'shippings' => $dateScope ]) // 仅返回时间段内有订单或发货申请的用户,排除无数据的用户 ->where(function ($builder) use ($dateScope) { $builder->whereHas('orders', $dateScope) ->orWhereHas('shippings', $dateScope); }) // 按周期内总业务量倒序排序 ->orderByRaw('orders_count + shippings_count DESC'); } else { // 无日期筛选时统计全量数据,按发货量倒序 $query->withCount(['orders', 'shippings']) ->orderBy('shippings_count', 'desc'); } // 分页获取结果,每页25条 $report = $query->paginate(25);
使用注意事项
- 建议传入日期参数前统一格式化:开始日期补
00:00:00,结束日期补23:59:59,避免遗漏结束日期当天晚些时候生成的数据 - 查询结果中每个用户模型会自动追加
orders_count、shippings_count两个属性,前端可直接读取渲染 - 所有or条件包裹在独立闭包中,后续新增用户状态、角色等筛选条件时不会出现逻辑冲突
内容的提问来源于stack exchange,提问作者Salma mehanny
相关产品推荐
相关产品推荐

