Laravel中统计关联及子关联表数据数量的实现方案
Laravel关联统计实现方案
针对你的需求,Laravel本身提供了简洁的实现方式,不需要自定义countWith方法,具体步骤如下:
1. 完善模型关联
首先在Operator模型中补充关联定义,包括和Locations的直接关联,以及通过Locations关联到Terminals的间接关联:
// app/Models/Operator.php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; class Operator extends Model { // 关联所属的Locations public function locations(): HasMany { return $this->hasMany(Location::class); } // 通过Locations关联到Terminals的间接关联 public function terminals(): HasManyThrough { return $this->hasManyThrough( Terminal::class, Location::class, 'operator_id', // Location表中关联Operator的外键 'location_id', // Terminal表中关联Location的外键 'id', // Operator表的主键 'id' // Location表的主键 ); } }
2. 执行统计查询
使用Laravel内置的withCount方法,一次性统计每个Operator对应的Locations数量和Terminals总数量:
$operators = Operator::withCount(['locations', 'terminals'])->get();
3. 使用统计结果
查询完成后,每个Operator实例会自动带上两个统计属性:
locations_count:当前Operator的Locations数量terminals_count:当前Operator下属所有Locations的Terminals总数量
你可以直接在后端将数据传递给Inertia,前端Vue3中就能这样展示:
<template> <table> <thead> <tr> <th>Operator名称</th> <th>Locations数量</th> <th>Terminals总数量</th> </tr> </thead> <tbody> <tr v-for="operator in operators" :key="operator.id"> <td>{{ operator.name }}</td> <td>{{ operator.locations_count }}</td> <td>{{ operator.terminals_count }}</td> </tr> </tbody> </table> </template>
替代方案(无需定义HasManyThrough)
如果不想定义间接关联,也可以用子查询实现统计:
$operators = Operator::select('operators.*') ->withCount('locations') ->selectSub(function ($query) { $query->selectRaw('count(*)') ->from('terminals') ->join('locations', 'locations.id', '=', 'terminals.location_id') ->whereColumn('locations.operator_id', 'operators.id'); }, 'terminals_count') ->get();
内容的提问来源于stack exchange,提问作者Mirsad Batilovic
相关产品推荐
相关产品推荐

