Laravel中如何根据数组包含情况对查询结果进行排序?
Laravel按id是否在指定数组排序的实现方案
数据库层面排序(推荐,大数据量更高效)
直接通过SQL的CASE语句实现分组排序,在查询阶段完成排序,避免内存处理大量数据,性能更优。
假设你的模型是Post,选中的id数组为$selectedIds = [1, 3, 12, 32];:
- 升序:不在数组的元素排在前面
$selectedIds = [1, 3, 12, 32]; $ascSortedPosts = Post::query() ->orderByRaw("CASE WHEN id IN (?) THEN 1 ELSE 0 END", [$selectedIds]) ->orderBy('id') // 可选:同一分组内按id升序排列 ->get();
- 降序:在数组的元素排在前面
只需给CASE语句的排序结果加上DESC:
$selectedIds = [1, 3, 12, 32]; $descSortedPosts = Post::query() ->orderByRaw("CASE WHEN id IN (?) THEN 1 ELSE 0 END DESC", [$selectedIds]) ->orderBy('id') // 可选:同一分组内按id升序排列 ->get();
集合层面排序(小数据量适用)
如果数据量不大,也可以先查询全量数据,再通过Laravel集合的排序方法处理:
- 升序:不在数组的元素排在前面
$selectedIds = collect([1, 3, 12, 32]); $ascSortedPosts = Post::all() ->sortBy(fn($post) => $selectedIds->contains($post->id) ? 1 : 0) ->values(); // 重置集合索引
- 降序:在数组的元素排在前面
$selectedIds = collect([1, 3, 12, 32]); $descSortedPosts = Post::all() ->sortByDesc(fn($post) => $selectedIds->contains($post->id) ? 1 : 0) ->values(); // 重置集合索引
补充说明
你之前用orderBy()加回调无效,是因为orderBy()仅支持字段名或原生SQL语法,不能直接传入闭包——闭包是集合排序的专属用法。
内容的提问来源于stack exchange,提问作者Kazi Nahian
相关产品推荐
相关产品推荐

