问题是为什么需要“嵌套查询”?我们不需要使用“嵌套查询”,这是在 SQL 而不是关系代数的思维方式中思考的。使用关系代数,我们推导出关系并将一个关系的输出用作另一个关系的输入,因此以下情况成立:
points = Table(:points, {:as => 'sorted'}) # rename in the options hash
final_points = points.order('timestamp DESC').group(:client_id, :timestamp).project(:client_id, :timestamp)
除非绝对必要,否则最好将重命名保留为 arel。
在这里,client_id 和时间戳的投影非常重要,因为我们不能从关系中投影所有域(即 sorted.*)。您必须专门规划将在关系的分组操作中使用的所有域。原因是 * 没有明确代表分组 client_id 的值。例如说你有下表
client_id | score
----------------------
4 | 27
3 | 35
2 | 22
4 | 69
在这里,如果您分组,则无法在分数域上执行投影,因为该值可能是 27 或 69,但您可以投影总和(分数)
您只能将具有唯一值的域属性投影到组(通常是聚合函数,如 sum、max、min)。对于您的查询,这些点是否按时间戳排序并不重要,因为最终它们将按 client_id 分组。时间戳顺序无关紧要,因为没有单个时间戳可以代表一个分组。
请让我知道如何帮助您处理 Arel。此外,我一直在制作一个学习系列,供人们使用 Arel 作为其核心。该系列的第一篇在http://Innovative-Studios.com/#pilot
我可以告诉你,因为你使用 Table(:points) 而不是 ActiveRecord 模型 Point,所以你开始知道如何使用了。