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

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>

关键说明

  1. 左连接的作用:leftJoin会保留categories表的所有记录,即使ads_listings中没有对应的数据,此时COUNT(ads_listings.id)会返回0,正好满足无帖子分类的统计需求。
  2. 父分类数量计算:因为你的帖子都是关联到子分类的,所以一级分类的数量需要汇总其下所有子分类的帖子数,我们通过遍历统计的方式实现了这一点。
  3. 层级展示:视图中通过判断parent_category_id来区分一级和子分类,让结构更清晰,符合你给出的示例格式。

内容的提问来源于stack exchange,提问作者toma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:40:34