Laravel whereIn 的排序问题

文章目录

    场景

    由于浏览历史记录表数据量巨大,所以不敢用这个表进行联表操作。

    在帖子浏览记录接口逻辑中,先获取了最近的浏览帖子的 ID 集合,然后使用 where in 操作获取具体的帖子信息。

    $saves = VisitHistory::where('user_id', $user->id)
        ->orderBy('id', 'desc')
        ->offset($offset)
        ->limit($limit)
        ->get();
    
    $items = Post::with('user:id,name,is_master,avatar_url')
        ->whereIn('id', $saves->pluck('post_id')->toArray())
        ->where('status', 1)
        ->get();
    

    排序问题

    但是这样做,会造成一个 bug,返回的帖子列表,并不是按照浏览顺序返回的。因为 where in 默认是不保证顺序的。

    解决方案

    使用 ORDER BY FIELD 语句。

    例如:

    SELECT * FROM posts WHERE id IN (2, 7, 6, 9, 1) 
    ORDER BY FIELD(id, 2, 7, 6, 9, 1)
    

    对应的 laravel 实现

    $saves = VisitHistory::where('user_id', $user->id)
        ->orderBy('id', 'desc')
        ->offset($offset)
        ->limit($limit)
        ->get();
    
    $ids = $saves->pluck('post_id')->toArray();
    $ids_ordered = implode(',', $ids);
    
    $items = Post::with('user:id,name,is_master,avatar_url')
        ->whereIn('id', $ids)
        ->where('status', 1)
        ->orderByRaw(DB::raw("FIELD(id, $ids_ordered)"))
        ->get();
    

    参考

    • https://stackoverflow.com/questions/26704575/laravel-order-by-where-in
    • https://stackoverflow.com/questions/3799935/mysql-select-where-in-given-order/3799966

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式