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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:38:20