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

Laravel中能否将三个SELECT查询合并为一个查询?

可以合并!两种方案帮你搞定

当然能把这三个查询合并成一个——而且还能优雅处理空结果的情况,具体分两种场景来实现:

方案一:利用Eloquent关联(推荐,更符合Laravel风格)

首先得确保你的三个模型之间已经定义了正确的关联关系(如果还没定义,先补上):

1. 定义模型关联

在Category模型中添加关联:

public function subcategories()
{
    // 第二个参数是Subcategory表中关联Category的外键,对应你原查询里的`sub_id`
    return $this->hasMany(Subcategory::class, 'sub_id');
}

在Subcategory模型中添加关联:

public function subsubcategories()
{
    // 同理,这里的外键是SubSubcategory表中关联Subcategory的`subsub_id`
    return $this->hasMany(SubSubcategory::class, 'subsub_id');
}

2. 合并查询并筛选

通过嵌套预加载with(),可以一次性拉取所有关联数据,同时带上你的筛选条件:

$categoryTree = Category::where('cat_id', $mainCatId)
    ->with([
        // 筛选指定的子分类
        'subcategories' => function ($query) use ($catId) {
            $query->where('sub_id', $catId)
                  ->select(['subcat_id', 'subcategory_name', 'sub_id']); // 必须包含外键`sub_id`,否则Eloquent无法关联
        },
        // 筛选指定的子子分类
        'subcategories.subsubcategories' => function ($query) use ($subCatId) {
            $query->where('subsub_id', $subCatId)
                  ->select(['subsubcat_id', 'subsubcategory_name', 'subsub_id']); // 同样要包含外键
        }
    ])
    ->select(['cat_id', 'category_name'])
    ->first(); // 按cat_id查询应该只有一条结果,用first比get更高效

空结果处理

  • 如果主分类不存在,$categoryTree会是null,可以用optional($categoryTree)或者简单的if判断来避免报错。
  • 如果子分类/子子分类为空,对应的属性会是一个空集合Collection,直接遍历也不会出问题。

方案二:使用原生Join查询(适合需要扁平结构的场景)

如果不想定义模型关联,或者需要扁平的数据集,可以用DB门面的leftJoin来合并查询,同时保证空结果不会导致整个查询返回空:

$combinedData = DB::table('categories')
    // Left Join保证即使子分类为空,主分类数据依然返回
    ->leftJoin('subcategories', function ($join) use ($catId) {
        $join->on('categories.cat_id', '=', 'subcategories.sub_id')
             ->where('subcategories.sub_id', '=', $catId);
    })
    // 同理,Left Join处理子子分类的空结果
    ->leftJoin('subsubcategories', function ($join) use ($subCatId) {
        $join->on('subcategories.subcat_id', '=', 'subsubcategories.subsub_id')
             ->where('subsubcategories.subsub_id', '=', $subCatId);
    })
    ->where('categories.cat_id', '=', $mainCatId)
    ->select(
        'categories.cat_id',
        'categories.category_name',
        'subcategories.subcat_id',
        'subcategories.subcategory_name',
        'subsubcategories.subsubcat_id',
        'subsubcategories.subsubcategory_name'
    )
    ->get();

这种方式返回的是扁平的数组/对象,某一层没有数据时,对应的字段会是null,不会丢失上层的有效数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:29:42