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
相关产品推荐
相关产品推荐

