Laravel关联统计:通过Has Many生成成员数数组及百分比计算
Laravel: 生成所有定居点的成员统计数组及百分比计算
看起来你遇到的问题是循环里没有把每个定居点的统计值存入数组,而是每次都覆盖了变量,所以最后只得到了最后一个定居点的数据。别担心,我们可以通过初始化数组并在循环中追加元素来解决这个问题,同时还能优化查询性能。
问题根源
你原来的循环代码:
foreach ($settlements as $settlement) { $sett = $settlement->members->count(); }
每次循环都会把$sett重新赋值为当前定居点的成员数,循环结束后$sett只会保留最后一次循环的值,而不是所有定居点的数组集合。
解决方案:生成统计数组并计算百分比
我们可以初始化三个空数组,分别存储所有定居点的总成员数、cipher_id=0的成员数和对应百分比,然后在循环中逐个添加数据:
优化后的Controller代码
// 预加载统计数据,避免N+1查询(性能优化) $settlements = Settlement::where('town_id', Auth::user()->town_id) ->where('reon_id', '1') ->withCount([ 'members', // 统计每个定居点的总成员数,自动生成members_count字段 'members as cipher_zero_count' => function ($query) { $query->where('cipher_id', 0); // 统计cipher_id=0的成员数,生成cipher_zero_count字段 } ]) ->get(); // 初始化空数组 $totalMembers = []; $cipherZeroMembers = []; $percentages = []; foreach ($settlements as $settlement) { $total = $settlement->members_count; $cipherZero = $settlement->cipher_zero_count; // 将统计值加入对应数组 $totalMembers[] = $total; $cipherZeroMembers[] = $cipherZero; // 计算百分比,处理总成员数为0的情况(避免除以0错误) $percentage = $total > 0 ? ($cipherZero / $total) * 100 : 0; $percentages[] = round($percentage, 2); // 保留两位小数,可按需调整精度 } // 将数据传递到视图 return view('your-view-path', compact('settlements', 'totalMembers', 'cipherZeroMembers', 'percentages'));
关键说明
- 使用
withCount优化查询:原来的$settlement->members->count()会为每个定居点单独执行一次查询(N+1问题),而withCount可以在一次查询中完成所有统计,大幅提升性能。 - 数组追加元素:通过
$array[] = $value的方式,把每个定居点的统计值添加到数组末尾,最终得到包含所有数据的完整数组。 - 处理除以0的情况:如果某个定居点总成员数为0,直接将百分比设为0,避免运行时错误。
在View中使用数组
如果需要在Google Charts中使用这些数组,可以直接用json_encode输出:
// 示例:输出总成员数数组 var totalMembers = {{ json_encode($totalMembers) }}; // 输出cipher_id=0的成员数数组 var cipherZeroMembers = {{ json_encode($cipherZeroMembers) }}; // 输出百分比数组 var percentages = {{ json_encode($percentages) }};
这样你就能得到所有定居点的统计数组,以及对应的百分比数组啦!
内容的提问来源于stack exchange,提问作者Nenad M
相关产品推荐
相关产品推荐

