【问题标题】:Sorting UNION queries with Laravel 4.1使用 Laravel 4.1 对 UNION 查询进行排序
【发布时间】:2014-02-25 04:45:19
【问题描述】:

我认为 Laravel 4 和 Laravel 4.1 之间的 union 发生了一些变化。我有 2 个模型。

$photos = DB::table('photos')->select('id', 'name', 'created_at');
$videos = DB::table('videos')->select('id', 'name', 'created_at');

我想合并 2 个查询并使用 created_at 字段对 2 个查询进行排序。

$photos = $photos->orderBy('created_at', 'desc');
$combined = $photos->union($videos);

使用 Laravel 4,它给了我这个查询:

select `id`, `name`, `created_at` from `videos`
union
select `id`, `name`, `created_at` from `photos`
order by `created_at` desc

这没问题,它将两个查询的结果排序在一起。在 Laravel 4.1 中,它给了我这个查询:

(select `id`, `name`, `created_at` from `videos`)
union
(select `id`, `name`, `created_at` from `photos` order by `created_at` desc)

这会产生一个视频列表,然后是一个有序的照片列表。我需要一个列表来对组合查询进行排序。我希望 Laravel 给我这个查询:

(select `id`, `name`, `created_at` from `videos`)
union
(select `id`, `name`, `created_at` from `photos`)
order by `created_at` desc

如何让它在 Laravel 中工作?

【问题讨论】:

  • 您只将orderBy 应用于$photos,而不是$videos。为什么要订购视频?
  • 这看起来他们修复了一个错误。在旧版本中,它不使用括号,因此即使您只为一个子查询编写了排序,也会将排序应用于所有内容。
  • 如果您想订购整个结果,请尝试$combined->orderBy
  • 我在问题中添加了我想要的查询。
  • 仅供参考,这看起来像是导致更改的报告:github.com/laravel/framework/issues/2494

标签: php laravel laravel-4 eloquent


【解决方案1】:

我认为这是一个错误,尚未修复。尝试对联合查询进行排序时,我遇到了同样的问题。

$query1->union($query2)->orderBy('foo','desc') 

导致 order by 子句单独添加到 $query 1。

将 orderBy 分别添加到 $query1 和 $query2,然后像下面这样进行联合

$query1->orderBy('foo desc');
$query2->orderBy('foo desc');
$query1->union($query2);

这显然有效,但它不会产生与对联合结果执行 orderBy 相同的结果。

目前,解决方法似乎正在做类似的事情

$query = $query1->union($query2);
$querySql = $query->toSql();
$query = DB::table(DB::raw("($querySql order by foo desc) as a"))->mergeBindings($query);

这将产生如下查询:

select * from (
  (select a as foo from foo)
  union
  (select b as foo from bar)
) as a order by foo desc;

这就是诀窍。

【讨论】:

    【解决方案2】:

    我不太了解 Laravel,但我敢打赌这会做到:

    $photos = DB::table('photos')->select('id', 'name', 'created_at');
    $videos = DB::table('videos')->select('id', 'name', 'created_at');
    $combined = $photos->union($videos)->orderBy('created_at', 'desc');
    

    【讨论】:

    • 这将对单个查询进行排序,而不是对查询进行排序:(select id, name, created_at from videos order by created_at desc) union (select id , name, created_at from photos order by created_at desc)
    • 好吧,我说我不知道​​ Laravel。
    【解决方案3】:

    在这个拉取请求中似乎已修复:https://github.com/laravel/framework/pull/3901

    【讨论】:

    • 工作就像一个魅力。但是,如果新手提及他们需要通过composer update 进行更新,然后参考您提供的链接,将会有所帮助!
    【解决方案4】:

    如果您将 orderBy 方法添加到它们的链接中,它应该可以工作,如下所示:

    $photos = DB::table('photos')->select('id', 'name', 'created_at')->orderBy('created_at', 'desc');
    $videos = DB::table('videos')->select('id', 'name', 'created_at')->orderBy('created_at', 'desc');
    $combined = $photos->union($videos);
    

    现在,正如 Barmar 所说,Laravel 只知道应该对照片查询进行排序,因为您在第三行中执行了该操作,如果您像上面那样执行,则可以将其删除。

    【讨论】:

    • 这将对单个查询进行排序并将结果放在一个列表中,它不会对该列表进行排序。
    • 抱歉,我误解了这个问题。如果在那之后它不能与 $combined->orderBy(' describe', 'desc') 一起工作,我认为它不会,那么我和你一样迷路。
    【解决方案5】:

    您可以尝试使用DB::query(),如下所示:

    DB::query('(Select id,name,created_at from photos) 
               union 
               (Select id,name,created_at from videos) order by created_at ASC');
    

    我想我知道它会起作用。仍在寻找实际的解决方案!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 2016-03-23
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 2014-03-12
      相关资源
      最近更新 更多