Laravel Query Builder能否按Appends字段status排序?需用orderBy
如何对Laravel模型的追加属性
status使用orderBy排序 首先直接给结论:不能直接用orderBy('status')实现,因为你定义的status是Eloquent的追加属性(通过访问器生成),它只存在于模型实例中,数据库里并没有这个字段——而orderBy()是直接将指令发送给数据库执行的,数据库根本不知道status是什么,所以会报错。
不过别担心,要实现数据库层面的排序(也就是你要的orderBy方案,而非集合的sortBy),我们可以把status的判断逻辑搬到SQL语句里,用orderByRaw()结合CASE表达式来实现,这完全符合你的需求。
具体实现代码
根据你访问器里的逻辑,对应的SQL CASE语句可以这样写:
// 按status的字符串值排序(比如'Active' < 'Canceled'这样的字典序) YourModel::where(...) ->orderByRaw(" CASE someattribute WHEN 1 THEN 'Active' WHEN 2 THEN 'Canceled' // 这里补充你其他的判断分支 ELSE 'Some another status' END ASC ") ->get();
如果你的排序优先级不是基于字符串字典序,而是业务逻辑的顺序(比如想让'Active'排在最前面,然后是'Canceled',最后是其他状态),更稳妥的方式是给每个状态分配一个排序权重,避免字符串排序带来的意外:
// 按业务优先级排序,权重数字越小越靠前 YourModel::where(...) ->orderByRaw(" CASE someattribute WHEN 1 THEN 1 // Active WHEN 2 THEN 2 // Canceled ELSE 3 // 其他状态 END ASC ") ->get();
为什么这个方案符合你的要求
这个方式是在数据库层面完成排序的,本质上还是用了Eloquent的orderBy相关方法(orderByRaw是orderBy的原生SQL扩展),完全区别于集合的sortBy(后者是把所有数据加载到内存后再排序,数据量大时性能差很多)。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

