Laravel框架下如何实现Video表记录按指定多规则排序
Laravel Video模型自定义排序实现
直接在查询构造器中用原生条件排序即可实现要求的规则,数据库层排序性能优于集合内存处理,适合绝大多数业务场景。
前提说明
假设用来标识视频赛事状态的字段为contest_status,三个状态值分别对应ActiveContest/NotInContest/PastContest,如果你的状态判断逻辑是关联赛事表(比如判断关联赛事的起止时间),把下面CASE语句里的判断条件替换成实际业务逻辑即可。
实现代码
$videos = Video::query() // 第一优先级:进行中赛事的视频固定排在最前 ->orderByRaw(" CASE WHEN contest_status = 'ActiveContest' THEN 1 ELSE 2 END ASC ") // 活动分区内按Boost降序,Boost=1的内容置顶 ->orderByRaw("CASE WHEN contest_status = 'ActiveContest' THEN boost END DESC") // Boost值相同时,活动分区按Fill值降序排列 ->orderByRaw("CASE WHEN contest_status = 'ActiveContest' THEN fill END DESC") // 非活动类视频随机排序,不会干扰前面活动区的固定排序结果 ->orderByRaw("RAND()") ->get();
排序效果验证
对应给出的测试数据,固定排在最前的活动区视频顺序为:
Video 1 ActiveContest Boost = 1 Fill=80
Video 2 ActiveContest Boost = 0 Fill=100
Video 3 ActiveContest Boost = 0 Fill=20
剩余3条非活动类视频(含未参赛、往期赛事内容)每次查询都会随机打乱顺序,无固定位置。
注意事项
- 如果你使用的不是MySQL数据库,随机排序函数需要对应替换:PostgreSQL用
RANDOM(),SQL Server用NEWID() - 单表数据量超过10万条时,
RAND()全表随机性能较差,建议拆分查询:先取出固定排序的活动区视频,再单独随机取非活动区视频拼接,避免慢查询 - 如果Boost、Fill字段存在null值,可以在CASE语句里加
COALESCE函数处理默认值,避免排序结果不符合预期
内容的提问来源于stack exchange,提问作者Jordan0097
相关产品推荐
相关产品推荐

