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

Laravel中如何用Query Builder将MySQL查询结果转为多维数组

解决方案:用Query Builder查询并重组为多维数组

第一步:关联所有表查询出扁平数据

先通过join关联所有需要的表,查询出包含所有层级字段的扁平结果集:

$flatResults = DB::table('products')
    ->join('product_details', 'products.id', '=', 'product_details.product_id')
    ->join('subcategories', 'product_details.subcategory_id', '=', 'subcategories.id')
    ->join('product_attributes', 'product_details.id', '=', 'product_attributes.product_detail_id')
    ->join('sub_images', 'product_attributes.id', '=', 'sub_images.product_attribute_id')
    // 筛选活跃数据,可根据需求调整
    ->where('subcategories.is_active', true)
    ->where('product_details.is_active', true)
    ->select(
        // 给每个字段加别名避免冲突
        'products.id as product_id',
        'products.name as product_name',
        'products.description as product_description',
        'subcategories.id as subcategory_id',
        'subcategories.subcategory_name',
        'product_details.id as detail_id',
        'product_details.sku',
        'product_details.price',
        'product_attributes.id as attribute_id',
        'product_attributes.size_id',
        'product_attributes.color_id',
        'product_attributes.material_id',
        'product_attributes.brand_id',
        'product_attributes.rating',
        'sub_images.sub_image'
    )
    ->get();

第二步:将扁平数据重组为多维数组

利用Laravel集合的groupBy和map方法,逐层嵌套分组,构建目标结构:

$structuredData = $flatResults->groupBy('product_id')->map(function ($productRecords) {
    // 取当前产品的基础信息(同组内基础信息一致)
    $baseProduct = $productRecords->first();
    return [
        'id' => $baseProduct->product_id,
        'name' => $baseProduct->product_name,
        'description' => $baseProduct->product_description,
        'subcategories' => $productRecords->groupBy('subcategory_id')->map(function ($subcatRecords) {
            $baseSubcat = $subcatRecords->first();
            return [
                'id' => $baseSubcat->subcategory_id,
                'subcategory_name' => $baseSubcat->subcategory_name,
                'product_details' => $subcatRecords->groupBy('detail_id')->map(function ($detailRecords) {
                    $baseDetail = $detailRecords->first();
                    return [
                        'id' => $baseDetail->detail_id,
                        'sku' => $baseDetail->sku,
                        'price' => $baseDetail->price,
                        'product_attributes' => $detailRecords->groupBy('attribute_id')->map(function ($attrRecords) {
                            $baseAttr = $attrRecords->first();
                            return [
                                'id' => $baseAttr->attribute_id,
                                'size_id' => $baseAttr->size_id,
                                'color_id' => $baseAttr->color_id,
                                'material_id' => $baseAttr->material_id,
                                'brand_id' => $baseAttr->brand_id,
                                'rating' => $baseAttr->rating,
                                // 提取当前属性下的所有图片
                                'sub_images' => $attrRecords->pluck('sub_image')->filter()->toArray()
                            ];
                        })->values()->toArray(), // 重置数组键为连续索引
                    ];
                })->values()->toArray(),
            ];
        })->values()->toArray(),
    ];
})->values()->toArray();

关键说明

  • groupBy:按层级ID分组,将同层级的记录聚合到一起
  • map:遍历分组后的集合,重组为需要的数组结构
  • first():同组内的基础字段(如产品名称、分类名称)是一致的,取第一条即可
  • pluck('sub_image'):提取当前属性下的所有图片URL,filter()可过滤空值
  • values():重置数组键,避免用分组ID作为键,生成连续索引的数组

如果需要处理无关联数据的场景(比如某个产品属性没有图片),可以在对应层级添加判断,例如:

'sub_images' => $attrRecords->isNotEmpty() ? $attrRecords->pluck('sub_image')->filter()->toArray() : []

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 22:32:20