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

Laravel 9中如何正确合并多个模型获取非空轮播数据?

Laravel 9 合并两个模型非空slider字段作为轮播数据源实现

现有代码问题

  • merge() 是 Eloquent 集合的方法,无法直接在未执行get()的查询构造器实例上调用
  • 重复嵌套调用union()传入未执行的查询对象,会生成非法SQL语句
  • 逻辑冗余,不需要同时使用merge和union两种合并逻辑

实现方案

方案1:数据库层UNION合并(推荐,性能更优)

直接在数据库层面合并两个查询结果,避免多次查询后再做PHP层面的合并,适合数据量大的场景:

public function index()
{
    // 构建两个字段完全匹配的查询
    $productSliderQuery = Product::query()
        ->select('slider')
        ->whereNotNull('slider');
    $serviceSliderQuery = Service::query()
        ->select('slider')
        ->whereNotNull('slider');

    // 合并查询后统一执行获取结果
    $slideShows = $productSliderQuery->union($serviceSliderQuery)->get();

    return view('Home.index', compact('slideShows'));
}

方案2:集合层面merge合并(适合需要单独处理两类数据的场景)

先分别查询拿到两类数据的集合实例,再通过集合方法合并:

public function index()
{
    // 先执行查询拿到集合
    $productSliders = Product::query()
        ->select('slider')
        ->whereNotNull('slider')
        ->get();
    $serviceSliders = Service::query()
        ->select('slider')
        ->whereNotNull('slider')
        ->get();

    // 调用集合的merge方法合并结果
    $slideShows = $productSliders->merge($serviceSliders);

    return view('Home.index', compact('slideShows'));
}

补充说明

  • 使用数据库UNION时,所有参与合并的查询,select的字段数量、字段名必须完全一致,否则会抛出SQL语法错误
  • 如果需要区分轮播项的来源,可以额外查询标识字段,示例:
    $productSliderQuery = Product::query()
        ->selectRaw('slider, "product" as source_type')
        ->whereNotNull('slider');
    $serviceSliderQuery = Service::query()
        ->selectRaw('slider, "service" as source_type')
        ->whereNotNull('slider');
    
  • 集合merge()方法遇到相同主键的记录时,会用后合并集合的记录覆盖之前的记录,如果需要保留所有重复项,替换为concat()方法即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:12:27