laravel 按关系列排序

ve7v8dk2  于 2023-01-18  发布在  其他
关注(0)|答案(8)|浏览(180)

我有以下疑问:

$items = UserItems::with('item')
        ->where('user_id','=',$this->id)
        ->where('quantity','>',0)
        ->get();

我需要按项目订购。键入,所以我尝试:

$items = UserItems::with('item')
        ->where('user_id','=',$this->id)
        ->where('quantity','>',0)
        ->orderBy('item.type')
        ->get();

但我得到Unknown column 'item.type' in 'order clause'
我错过了什么?

mwg9r5ms

mwg9r5ms1#

join()运行良好,感谢@rypskar注解

$items = UserItems
        ::where('user_id','=',$this->id)
        ->where('quantity','>',0)
        ->join('items', 'items.id', '=', 'user_items.item_id')
        ->orderBy('items.type')
        ->select('user_items.*') //see PS:
        ->get();

PS:为了避免id属性(或两个表之间的任何共享名称属性)重叠并导致错误的值,应该使用select('user_items.*')指定选择限制。

jaql4c8m

jaql4c8m2#

您的急切加载可能没有构建您所期望的查询,您可以通过启用查询日志来检查它。
但我可能只会使用集合过滤器:

$items = UserItems::where('user_id','=',$this->id)
        ->where('quantity','>',0)
        ->get()
        ->sortBy(function($useritem, $key) {
          return $useritem->item->type;
        });
quhf5bfb

quhf5bfb3#

您可以使用withAggregate函数来解决问题

UserItems::withAggregate('item','type')
    ->where('user_id','=',$this->id)
    ->where('quantity','>',0)
    ->orderBy('item_type')
    ->get();
aoyhnmkz

aoyhnmkz4#

我知道这是一个老问题,但您仍然可以使用不带连接的“orderByRaw”。

$items = UserItems
        ::where('user_id','=',$this->id)
        ->where('quantity','>',0)
        ->orderByRaw('(SELECT type FROM items WHERE items.id = user_items.item_id)')
        ->get();
k7fdbhmy

k7fdbhmy5#

我发现了另一种使用相关模型中的字段对数据集进行排序的方法,您可以在模型中获得一个函数,该函数获得与相关表的唯一关系(例如:与房间类别相关的房间,并且房间通过类别ID与类别相关,您可以使用类似于'room_category'的函数,该函数基于房间模型的类别ID返回相关类别),之后的代码将如下所示:

Room::with('room_category')->all()->sortBy('room_category.name',SORT_REGULAR,false);

这将按类别名称对房间进行排序
我在一个项目中这样做,我有一个数据表与服务器端处理,我有一个案例,它需要排序的一个字段的相关实体,我这样做,它的工作。更容易,更适合MVC标准。
在您的情况下,它将以类似的方式:

User::with('item')->where('quantity','>',0)->get()->sortBy('item.type',SORT_REGULAR,false);
pftdvrlh

pftdvrlh6#

对于一对多关系,有一种更简单的方法。假设一个订单有许多付款,我们希望按最近的付款日期对订单排序。付款表有一个名为order_id的字段,该字段为FK。
我们可以这样写

$orders = Order->orderByDesc(Payment::select('payments.date')->whereColumn('payments.order_id', 'orders.id')->latest()->take(1))->get()

此代码的SQL等效项:

select * from orders order by (
    select date
    from payments
    where order_id = payments.id
    order by date desc
    limit 1
) desc

你可以根据你的例子来修改它。如果我理解正确的话,在你的情况下,订单的等价物是用户,支付的等价物是物品。
进一步阅读
https://reinink.ca/articles/ordering-database-queries-by-relationship-columns-in-laravel

xv8emn3q

xv8emn3q7#

$users
->whereRole($role)       
->join('address', 'users.id', '=', 'address.user_id')  
->orderByRaw("address.email $sortType")    
->select('users.*')
lvmkulzt

lvmkulzt8#

你可以简单地

UserItems::with('item')
  ->where('user_id','=',$this->id)
  ->where('quantity','>',0)
  ->orderBy(
      Item::select('type') 
      ->whereColumn('items.useritem_id','useritems.id')
      ->take(1),'desc'
    )    
  ->get();

相关问题