使用Laravel 4.1对UNION查询进行排序

时间:2014-02-01 12:12:30

标签: php laravel laravel-4 eloquent

我认为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中使用它?

5 个答案:

答案 0 :(得分:7)

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

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

使order by子句单独添加到$ query。

将orderBy分别添加到$ query1和$ query2,然后执行如下所示的联合

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

这显然有效,但它不会产生与在union的结果上执行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;

这就是诀窍。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

我真的不认识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');

答案 3 :(得分:0)

如果你将链接中的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只知道应该订购照片查询,因为你在第三行中这样做了,如果你这样做就可以删除。

答案 4 :(得分:0)

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

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

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