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

Laravel Eloquent关联查询:如何获取子表Income的created_at数据?

问题描述

我有两个关联的Laravel模型,代码如下:

Product 模型

public function IncomeRepo(){
    return $this->hasMany(Income::class,'Product');
}

Income 模型

public function ProductData(){
    return $this->belongsTo(Product::class,'Product','id');
}

当前查询方法

public function SearchIncomeData(Request $request){
    $GetFromDate = $request->FromDate;
    $GetToDate = $request->ToDate;
        
    $ProductData = Product::with('IncomeRepo')->whereBetween('created_at', [$GetFromDate, $GetToDate])->get();
        
    return view('Admin.Report.ProductSalesReport',compact('ProductData'));
}

现在遇到的问题是:返回的$ProductData只包含Product表的created_at数据,但我需要获取每个产品关联的Income表中多条对应的created_at数据,该怎么修改查询?


解决方案

你现在的查询是按Product表的创建时间筛选产品,但没有对关联的Income数据做时间过滤,而且默认加载的关联数据是该产品的所有Income记录。要拿到指定时间范围内Income的created_at,可以用两种方式实现:

方式一:过滤关联的Income数据(保留产品维度)

通过with()的闭包参数,给关联的IncomeRepo添加时间筛选条件,确保只加载指定时间范围内的Income记录,这样每个Product下的IncomeRepo集合里就会包含符合条件的记录,自然能拿到对应的created_at:

public function SearchIncomeData(Request $request){
    $GetFromDate = $request->FromDate;
    $GetToDate = $request->ToDate;
        
    $ProductData = Product::with(['IncomeRepo' => function($query) use ($GetFromDate, $GetToDate) {
        // 对关联的Income表添加时间范围筛选
        $query->whereBetween('created_at', [$GetFromDate, $GetToDate]);
    }])
    // 可选:如果只想返回有符合条件Income的产品,取消下面两行注释
    // ->whereHas('IncomeRepo', function($query) use ($GetFromDate, $GetToDate) {
    //     $query->whereBetween('created_at', [$GetFromDate, $GetToDate]);
    // })
    ->get();
        
    return view('Admin.Report.ProductSalesReport',compact('ProductData'));
}

方式二:从Income表反向查询(以销售记录为核心)

如果你的报表重点是销售记录(Income),可以直接从Income表出发,关联Product并筛选时间,这样能直接拿到每条Income的created_at和对应的产品数据:

public function SearchIncomeData(Request $request){
    $GetFromDate = $request->FromDate;
    $GetToDate = $request->ToDate;
        
    $IncomeData = Income::with('ProductData')
        ->whereBetween('created_at', [$GetFromDate, $GetToDate])
        ->get();
        
    // 可选:如果需要按产品分组展示,可添加以下代码
    // $groupedData = $IncomeData->groupBy('ProductData.id');
        
    return view('Admin.Report.ProductSalesReport',compact('IncomeData'));
}

注意事项

  • 确认Income表的created_at字段存在且时间格式正确;
  • 两种方式都能同时获取Product和Income的created_at,根据报表的展示逻辑选择即可;
  • 若使用方式一,不添加whereHas的话,会返回所有产品(即使该产品没有符合条件的Income记录)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:25:09