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的常见查询方法

Laravel / Eloquent - 无法执行原始查询

Laravel 验证使用 eloquent 或 raw 查询

Laravel:Mysql 查询到 Eloquent

Laravel Lumen - Eloquent 查询日志