首先,我要包括一些我尝试过的东西,因为我认为这对我正在尝试做的事情有很大的自我解释。
$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
查询。如何解决这个问题?
非常感谢 - 正确答案当然会被选中并作为答案选择。
答案 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);
第一种方法使用两个查询,这不是最优的 - 第二种方法使用了很多收集方法。
如果有人可以指出哪一个更有效,那将非常有帮助!