Laravel多个订单在同一列上

时间:2015-09-25 17:00:00

标签: laravel eloquent where eager-loading

首先,我要包括一些我尝试过的东西,因为我认为这对我正在尝试做的事情有很大的自我解释。

$event->load(['dates' => function($q) {

 $q->where( DB::raw('DATE(start_time)'), '>=', Carbon::now()->format('Y-m-d'))
   ->orderBy('start_time', 'asc')

   ->where( DB::raw('DATE(start_time)'), '<', Carbon::now()->format('Y-m-d'))
   ->orderBy('start_time', 'desc');

}]);

$event->load(['dates' => function($q) {

 $q->where( DB::raw('DATE(start_time)'), '>=', Carbon::now()->format('Y-m-d'))
   ->orderBy('start_time', 'asc')

   ->orWhere(function($query) {

     $query->where( DB::raw('DATE(start_time)'), '<', Carbon::now()->format('Y-m-d'))
           ->orderBy('start_time', 'desc');
     });

}]);

我正在尝试做什么

我有一个与DATES有hasMany关系的EVENTS表。我正在尝试为即将到来的日期以升序顺序加载相关日期第一,然后以降序顺序加载已经过去的日期过去了。

我尝试的任何内容,orderBy总是排序全部结果,而不是where查询。如何解决这个问题?

非常感谢 - 正确答案当然会被选中并作为答案选择。

2 个答案:

答案 0 :(得分:0)

您在同一查询中不能有两个不同的订单。但是你可以拥有的是两个子查询,每个子查询都有自己的顺序,union就像你想要的一样。{/ p>

答案 1 :(得分:0)

好吧,实际上找到了两个合适的解决方案来解决我的问题。感谢 @Bernie 让我朝着正确的方向努力 - 我在同一个查询中不能有两个不同的订单,并寻找像 union / merge 这样的东西。

使用多个查询

第一行急切加载只是$event中的即将到来的日期

其次,您获得过去的日期,第三次将它们合并在一起。

唯一不好的事情 - 你必须执行多个(两个)查询,这不是最佳的。

    $event->load(['dates' => function($q) {
        $q->where( DB::raw('DATE(start_time)'), '>=', Carbon::now()->format('Y-m-d') )
          ->orderBy('start_time');
    }]);

    $past = $event->dates()
                  ->where( DB::raw('DATE(start_time)'), '<', Carbon::now()->format('Y-m-d') )
                  ->orderBy('start_time', 'desc')                 
                  ->get();

    $event->dates = $event->dates->merge($past);

收集方法

首先急切加载所有属于该事件的日期。

第二个filter所有过去日期reverse - 所有这一切都是通过收集方法

然后,您count过去的日期,splice来自原始的集合,并合并新的反向集合

    $event->load(['dates' => function($q) {
        $q->orderBy('start_time');
    }]);

    $filtered = $event->dates->filter(function ($item) {
        return $item->raw_date < Carbon::now()->format('Y-m-d');
    })->reverse();

    $event->dates->splice(0, $filtered->count());
    $event->dates = $event->dates->merge($filtered);

结论

第一种方法使用两个查询,这不是最优的 - 第二种方法使用了很多收集方法

如果有人可以指出哪一个更有效,那将非常有帮助!