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
相关产品推荐
相关产品推荐

