Laravel 5中按全类别统计帖子数量的问题求助
解决按全分类统计帖子数量的问题
我明白你的需求啦——你希望展示所有分类(哪怕没有帖子的分类也要显示0),并且一级分类的数量是其下所有子分类的帖子总和,就像vehicles(3) cars(2) motorbike(1) cycle(0)这样的效果。当前代码只统计了有帖子关联的子分类,我们需要调整查询逻辑和视图展示来实现目标:
第一步:修改控制器的统计逻辑
原来的内连接(join)只会返回两边都有匹配数据的记录,所以没有帖子的分类会被过滤掉。我们改用**左连接(leftJoin)**来保留所有分类,同时计算父分类的帖子总数(子分类的数量之和)。修改后的控制器代码如下:
public function countListingsByCategories() { // 先统计每个分类直接关联的帖子数(子分类的直接帖子数) $categoryData = DB::table('categories') ->leftJoin('ads_listings', 'categories.id', '=', 'ads_listings.category_id') ->select( 'categories.id', 'categories.category_title', 'categories.parent_category_id', DB::raw('COUNT(ads_listings.id) as direct_count') ) ->groupBy('categories.id', 'categories.category_title', 'categories.parent_category_id') ->get(); // 计算每个一级分类的总帖子数(子分类数量之和) $parentTotalCounts = []; foreach ($categoryData as $category) { if ($category->parent_category_id != 0) { $parentId = $category->parent_category_id; $parentTotalCounts[$parentId] = ($parentTotalCounts[$parentId] ?? 0) + $category->direct_count; } } // 合并结果,给每个分类赋值最终的帖子数 $finalCategoryCounts = $categoryData->map(function ($category) use ($parentTotalCounts) { // 一级分类取子分类的总和,子分类取直接统计的数量 $category->num_listings = $category->parent_category_id == 0 ? ($parentTotalCounts[$category->id] ?? 0) : $category->direct_count; return $category; }); // 按层级排序:先一级分类,再子分类 return $finalCategoryCounts->sortBy('parent_category_id')->sortBy(function ($cat) { return $cat->parent_category_id == 0 ? 0 : $cat->id; }); }
第二步:调整视图展示层级
为了更清晰地展示一级分类和子分类的关系,我们修改视图代码,让子分类嵌套在对应的一级分类下:
<ul class="row catelist"> @foreach($categoriesNumListings as $mainCategory) {{-- 渲染一级分类 --}} @if($mainCategory->parent_category_id == 0) <li class="col-md-12 main-category"> <a href="{{ route('view.listings.by.category', $mainCategory->category_title) }}" title="{{ $mainCategory->category_title }} ads"> {{ $mainCategory->category_title }} <span>({{ $mainCategory->num_listings }} Listings)</span> </a> {{-- 渲染该一级分类下的所有子分类 --}} <ul class="sub-categories col-md-12"> @foreach($categoriesNumListings as $subCategory) @if($subCategory->parent_category_id == $mainCategory->id) <li> <a href="{{ route('view.listings.by.category', $subCategory->category_title) }}" title="{{ $subCategory->category_title }} ads"> {{ $subCategory->category_title }} <span>({{ $subCategory->num_listings }} Listings)</span> </a> </li> @endif @endforeach </ul> </li> @endif @endforeach </ul>
关键说明
- 左连接的作用:
leftJoin会保留categories表的所有记录,即使ads_listings中没有对应的数据,此时COUNT(ads_listings.id)会返回0,正好满足无帖子分类的统计需求。 - 父分类数量计算:因为你的帖子都是关联到子分类的,所以一级分类的数量需要汇总其下所有子分类的帖子数,我们通过遍历统计的方式实现了这一点。
- 层级展示:视图中通过判断
parent_category_id来区分一级和子分类,让结构更清晰,符合你给出的示例格式。
内容的提问来源于stack exchange,提问作者toma
相关产品推荐
相关产品推荐

