# [技巧] 巧用数据集的排序和过滤功能 经常会遇到一些业务统计的需求,每次查询都是动态计算的,例如查询一个用户列表,并包含一个每一个用户的总分(统计)数据。 ``` // 关联查询用户的总成绩 User::withSum('Score', 'score')->select(); ``` 由于涉及到聚合查询以及多表关联查询,所以如果要对总分进行排序并不是特别的方便,我们可以用数据集自带的排序功能来实现统计数据的排序。 ``` // 关联查询用户的总成绩 $users = User::withSum('Score', 'score')->select(); // 把按照总分由高到低排序 // score_sum是withSum默认返回的统计字段名称 $users = $users->order('score_sum', 'desc'); ``` >[info] 这个例子使用了`withSum`,实际应用中并非必须。如果使用的是获取器方式获取的统计和动态数据都可以适用于数据集的排序方法。 >[danger] 但如果使用了分页查询,则只能用于当前页的内容排序,请谨慎使用。 这是一种相对比较高性能和低成本的统计结果排序的解决方案,当然,如果对统计结果没有实时性的要求的话,建议使用查询缓存提升查询性能。 除了对结果排序之外,数据集还有很多方便的方法,这里顺便提下。 如果你需要对查询的结果进行分批次的处理,每次需要过滤一些不同的数据,可以使用 ``` // 模型查询返回数据集对象 $users = User::where('score', '>', 0)->select(); // 成绩在90分以上的用户 $list1 = $users->where('score', '>=', 90); // 成绩在80分和90分之间的用户 $list2 = $users->where('score', '<', 90)->where('score', '>=', 80); ``` 对于一些数据的并集、交集以及差集的处理,也可以通过数据集的相关方法来完成。 ``` // 查询具有测试(角色)权限的用户 $list1 = User::hasWhere('Role', ['role'=>'test'])->field('id,name')->select(); // 查询具有编辑(角色)权限的用户 $list2 = User::hasWhere('Role', ['role'=>'editor'])->field('id,name')->select(); // 获取有测试权限但没有编辑权限的用户 dump($list1->diff($list2)); // 获取同时有测试权限和编辑权限的用户 dump($list1->intersect($list2)); ``` 关于数据集的更多方法可以参考手册。