Laravel whereIn 的排序问题

更新日期: 2019-05-08 阅读次数: 1726 字数: 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

关于作者

我是来自山东烟台的一名开发者,喜欢瞎折腾,顺便记记笔记。有敢兴趣的话题,欢迎加微信 zhongwei 聊聊。 白天工地搬砖,晚上哄熊孩子,可能回复有点慢,见谅。 查看更多联系方式

相关文章

爱评论不评论

近期节日

2019年11月20日 国际儿童日
2019年11月21日 世界问候日
2019年11月22日 小雪
2019年11月22日 感恩节
2019年11月29日 黑色星期五
2019年12月01日 世界艾滋病日
2019年12月03日 国际残疾人日
2019年12月07日 大雪
2019年12月09日 "一二九"运动纪念日
2019年12月09日 世界足球日
2019年12月10日 世界人权日
2019年12月12日 西安事变纪念日
查看更多节日