Laravel whereIn 的排序问题

更新日期: 2019-05-08 阅读次数: 162 字数: 199 分类: Laravel

场景

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

在帖子浏览记录接口逻辑中,先获取了最近的浏览帖子的 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

爱评论不评论

近期节日

2019年05月20日 全国助残日
2019年05月21日 小满
2019年05月30日 五卅运动纪念
2019年05月31日 世界无烟日
2019年06月01日 六一儿童节
2019年06月05日 世界环境日
2019年06月06日 芒种
2019年06月06日 全国爱眼日
2019年06月07日 端午节
2019年06月11日 中国人口日
2019年06月16日 父亲节
2019年06月20日 世界难民日
查看更多节日