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

Laravel带WHERE条件关联查询:获取含最大total零件的工具

在Laravel中获取关联最大total零件的工具

没问题,我来帮你搞定这个多表关联查询的需求!首先咱们得先把模型之间的关联关系定义好,这是Eloquent查询的基础:

1. 定义模型关联

Tool模型(app/Models/Tool.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Tool extends Model
{
    // 如果你的表名是`tools`,Laravel默认会自动识别,这行可以省略,写上更清晰
    protected $table = 'tools';

    // 一个Tool对应多个Part
    public function parts(): HasMany
    {
        return $this->hasMany(Part::class, 'tool_id');
    }
}

Part模型(app/Models/Part.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Part extends Model
{
    protected $table = 'parts';

    // Part属于一个Tool
    public function tool(): BelongsTo
    {
        return $this->belongsTo(Tool::class, 'tool_id');
    }

    // 一个Part对应多个PartDetail
    public function partDetails(): HasMany
    {
        return $this->hasMany(PartDetail::class, 'part_id');
    }
}

PartDetail模型(app/Models/PartDetail.php)

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class PartDetail extends Model
{
    // 你的表名是`part_details`,这里要明确指定
    protected $table = 'part_details';

    // PartDetail属于一个Part
    public function part(): BelongsTo
    {
        return $this->belongsTo(Part::class, 'part_id');
    }
}

2. 不同场景的查询方法

场景1:获取整个系统中,关联着拥有最大total值的零件的工具

也就是找到part_details表中total最大的那条记录,然后追溯到它所属的Tool。

方法A:分步查询(简单直观)

// 先拿到最大的total值
$maxTotal = \App\Models\PartDetail::max('total');

// 再找到对应的Tool
$targetTool = \App\Models\Tool::whereHas('parts.partDetails', function ($query) use ($maxTotal) {
    $query->where('total', $maxTotal);
})->first();

方法B:子查询(一次DB请求,更高效)

$targetTool = \App\Models\Tool::whereHas('parts.partDetails', function ($query) {
    $query->where('total', \App\Models\PartDetail::selectRaw('MAX(total)'));
})->first();

如果有多个Tool关联的零件都有相同的最大total,把first()改成get()就能拿到所有符合的工具集合。


场景2:给每个Tool,获取其关联零件中total最大的那个(返回所有工具及其对应最大total的零件)

比如要展示每个工具下性能最好(total最大)的零件,用下面的写法:

方法A:关联子查询带自定义字段

$tools = \App\Models\Tool::with(['parts' => function ($query) {
    // 给每个Part添加它的最大total值字段
    $query->addSelect(['max_total' => \App\Models\PartDetail::selectRaw('MAX(total)')
            ->whereColumn('part_id', 'parts.id')])
        // 按max_total降序排列,确保每个Tool的第一个Part是最大的
        ->orderByDesc('max_total');
}])->get();

方法B:直接关联取最大的PartDetail

如果只需要每个Tool下最大total的那条PartDetail记录,可以这样写:

$tools = \App\Models\Tool::with(['parts.partDetails' => function ($query) {
    // 对每个Part的PartDetail按total降序,只取第一条(最大的)
    $query->orderByDesc('total')->take(1);
}])->get();

场景3:用原生查询构建器(追求极致性能)

如果你的查询逻辑很复杂,也可以直接用DB门面写原生风格的查询:

$targetTool = \Illuminate\Support\Facades\DB::table('tools')
    ->join('parts', 'tools.id', '=', 'parts.tool_id')
    ->join('part_details', 'parts.id', '=', 'part_details.part_id')
    ->orderByDesc('part_details.total')
    ->select('tools.*')
    ->first();

这个方法和场景1的效果一致,适合不需要Eloquent模型特性的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:48:28