在rails中,给定Point对象数组,如何对每个玩家的点值求和?

时间:2017-05-18 17:25:55

标签: sql ruby-on-rails ruby postgresql activerecord

我们正在为这个项目使用postgres。

目标是获得一个哈希值,将每个玩家与其点值之和进行配对。

我有一组Point个对象,看起来像这样:

注意:这里的每个哈希实际上都是来自Points.where的数据库对象。该数组实际上是ActiveRecord:Relation个实例)

[
    { value: 3, player_id: 55 },
    { value: 1, player_id: 21 },
    { value: 2, player_id: 55 },
    { value: 6, player_id: 23 },
    { value: 2, player_id: 78 },
    { value: 2, player_id: 55 },
    { value: 5, player_id: 80 },
    { value: 7, player_id: 21 },
    { value: 2, player_id: 23 },
    { value: 1, player_id: 78 },
    { value: 4, player_id: 80 }
]

预期的输出结果如下:

{
    55: 7,
    21: 8,
    23: 8,
    78: 3,
    80: 9
}

其中键是player_id,值是所有点值的总和。

我想出的ruby中的一个解决方案是使用activerecord来对集合中每个ID的点进行求和。

points = get_the_points()

point_map = {}
ids = points.pluck(:player_id)

player_ids.each do |id|
    points_for_id = points.where(player_id: id).pluck(:value)
    sum_of_points = points_for_id.sum

    point_map[id] = sum_of_points
end

return point_map

但我知道这可以用SQL完成,我知道它会更快。

因为我只是在处理一个模型,所以我不必使用连接或任何东西,是吗?

2 个答案:

答案 0 :(得分:2)

尝试一个SQL查询

Point.group(:player_id).sum(:value)

答案 1 :(得分:1)

在纯SQL中,我们需要类似的东西:

SELECT points.user_id, SUM(points.value) AS sum_value
FROM points
GROUP BY points.user_id;

按行user_id对行进行分组,并获取points.value的汇总。

 user_id | sum_value 
---------+-----------
      14 |        18
      25 |        19
      17 |        29
      12 |        14
       8 |         9
       1 |        16
      15 |        19
      10 |        37
      11 |        26
       4 |        43

要在Rails中获得相同的查询,您可以使用:

Point.group(:user_id).sum(:value)
  

因为我只是在处理一个模型,所以我不必使用连接或任何东西,是吗?

除非您想要列出用户名和分数的高分列表,否则不会这样做。