Laravel Eloquent Union 查询
Posted
技术标签:
【中文标题】Laravel Eloquent Union 查询【英文标题】:Laravel Eloquent Union query 【发布时间】:2017-06-05 00:21:08 【问题描述】:所以我有以下查询:
$a = Model::where('code', '=', $code)
->where('col_a', '=' , 1)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))
$b = Model::where('code', '=', $code)
->where('col_b', '=' , 1)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))
$a->union($b)->get();
当我先 'orderBy()' 然后联合时,没有排序发生。
当我单独查询 '$a' 或 '$b' 时,'orderBy()' 工作正常。
当我按照以下方式执行时,'orderBy()' 会作为一个整体发生。
$a->union($b)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))
->get();
我怎样才能使'orderBy()'单独应用于每个,然后将结果合并回来?看来应该可以了。
编辑:如果有人可以提供一种方法来做到这一点,即使它是普通的 mysql,我也会选择你的作为答案,因为我认为 Eloquent 可能存在错误。
【问题讨论】:
为什么它“不起作用”。错误或输出是什么 没有错误。它似乎没有应用 orderBy 排序。 这不是 Eloquent 的东西,而是 MySQL 的东西。请参阅此处接受的答案中的“跟进”:***.com/questions/24683766/…。基本上:在 UNION 中 ORDER BY 将被忽略,甚至可能依赖于 MySQL 的版本。 【参考方案1】:尝试以下方法:
$a = Model::where('code', '=', $code)
->where('col_a', '=' , 1);
$b = Model::where('code', '=', $code)->where('col_b', '=' , 1)
->union($a)
->get();
$result = $b;
【讨论】:
但如果两个表的列数不同,则会出错。有什么方法可以让 UNION 与 diff 列表在 eloquent 中使用? @Sunil 对我来说,在不同数量的列中合并是不可能的。除非您将添加具有空值的选择盟友。 UNION 中的每个 SELECT 语句必须具有相同的列数。这些列还必须具有相似的数据类型。每个 SELECT 语句中的列的顺序也必须相同。【参考方案2】:Laravel 集合中的 “合并” 功能或许可以帮到你。 最大的不同是我提前用 ->get() 关闭查询,我使用 merge() 而不是 union()
$a = Model::where('code', '=', $code)
->where('col_a', '=' , 1)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))->get();
$b = Model::where('code', '=', $code)
->where('col_b', '=' , 1)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))->get();
$result = $a->merge($b);
注意:我没有你的数据,所以我无法证明它有效,但它至少适用于我的数据,所以值得你尝试
【讨论】:
我添加了 ->get();到您的示例 $a 和 $b 的末尾。您提供的解决方案可以工作,但需要为每个解决方案访问数据库,这是我试图避免的,因为我需要多个联合,但这是目前最好的答案。 当需要以正确的排序顺序对合并结果进行分页时,它不起作用【参考方案3】:尝试在union()
之后申请orderBy()
试试这个
$a->union($b)->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))->get();
编辑
研究并发现并准备了雄辩的查询,试试这个
$modelA = Model::where('code', '=', $code)
->where('col_a', '=' , 1)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))
$modelB = Model::where('code', '=', $code)
->where('col_b', '=' , 1)
->orderBy(DB::raw('FIELD(layout, "normal", "split", "flip", "double-faced", "") ASC, layout'))
$a = DB::table(DB::raw("($modelA->toSql()) as a"))
->mergeBindings($modelA->getQuery())
->selectRaw("a.*");
$b = DB::table(DB::raw("($modelB->toSql()) as b"))
->mergeBindings($modelB->getQuery())
->selectRaw("b.*");
$a->union($b)->get();
【讨论】:
我不希望它作为一个整体订购。我希望各个查询在其内部进行排序。 你可以发布没有联合和联合的结果以了解更多关于问题的信息 这会很困难,因为我简化了问题的查询。当我先 orderBy() 然后联合时,基本上没有排序发生。当我单独执行它们时, orderBy() 工作正常。当我根据您发布 orderBy() 的答案执行此操作时,会作为一个整体发生。 我认为这可能是一个 Laravel 错误。我在 github 上发布了这个错误。希望它会尽快得到解决。 @PrafullaKumarSahu 正在检查。以上是关于Laravel Eloquent Union 查询的主要内容,如果未能解决你的问题,请参考以下文章
在 Laravel Eloquent 中,你如何在联合范围之外进行两个联合查询和一个选择?
php [Eloquent CheatSheet] Eloquent #laravel #eloquent的常见查询方法