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

Laravel 5.4:如何在Eloquent的whereHas中使用groupBy

在Laravel 5.4的whereHas闭包中使用groupBy的解决方案

其实很简单,你可以直接在whereHas的关联查询闭包里调用groupBy方法——因为闭包中的$query是针对关联表(这里是orderDetail对应的表)的查询构建器实例,所有查询构建器支持的方法(包括分组、聚合、过滤等)都能在这里正常使用。

修改后的完整代码示例

use Illuminate\Support\Facades\Auth;

public function index(Request $request) {
    $dateFrom = $request->get('dateFrom');
    $dateTo = $request->get('dateTo');
    $status = $request->get('orderState');
    
    $orders = (new OrderList())
        ->whereHas('orderDetail', function ($query) {
            $query->where('supplier_id', Auth::guard('supplier')->user()->id)
                  // 替换成你实际需要分组的字段,比如关联表中的order_id
                  ->groupBy('order_id'); 
        })
        ->when($dateFrom, function ($query) use ($dateFrom, $dateTo) {
            // 补全你之前的时间范围过滤逻辑,比如针对订单创建时间
            $query->whereBetween('created_at', [$dateFrom, $dateTo]);
        })
        // 可选:根据订单状态添加过滤条件
        ->when($status, function ($query) use ($status) {
            $query->where('order_state', $status);
        })
        ->get();

    return $orders;
}

进阶用法:结合聚合函数与having过滤

如果你需要在分组后基于聚合结果进一步筛选(比如只保留关联记录数大于1的订单),可以配合select和havingRaw实现:

use Illuminate\Support\Facades\DB;

// ...其他代码不变
->whereHas('orderDetail', function ($query) {
    $query->where('supplier_id', Auth::guard('supplier')->user()->id)
          ->select('order_id', DB::raw('count(*) as item_count'))
          ->groupBy('order_id')
          // 只保留关联商品数量大于1的订单
          ->havingRaw('item_count > 1');
})
// ...其他代码不变

注意事项

  • 如果开启了MySQL严格模式,groupBy需要包含所有select语句中的非聚合字段,否则会抛出SQL语法错误。
  • whereHas的核心作用是筛选出存在符合条件关联记录的主模型(OrderList),所以分组操作只会影响关联表的查询逻辑,不会直接改变主模型的结果结构(如果需要统计关联数据,可以配合withCount方法)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:43:25