【问题标题】:Leaderboard for sum of points / number of games积分总和/游戏数排行榜
【发布时间】:2018-09-12 16:02:39
【问题描述】:

我有统计模型:

Stat(id: integer, points: float, user_id: integer, match_id: integer, team_id: integer)

对于匹配模型:

 Match(id: integer, team_a_id: integer, team_b_id: integer)

Stat 可以与相同的 user_id 和 match_id 重复。我需要的是获得每个user_id 的SUM 点数,然后将其除以match_id 的数量,即玩过的游戏。

例子:

{id: 1, points: 2, user_id: 1, match_id: 1, team_id: 1}
{id: 2, points: 3, user_id: 1, match_id: 1, team_id: 1}
{id: 3, points: 4, user_id: 1, match_id: 2, team_id: 1}

所以在这里我有 2 场比赛。我需要得到user_id 的总和,然后将其除以他的游戏数,即 2(match_id 1 和 2)。然后得到前10个最高指针。

【问题讨论】:

    标签: ruby-on-rails ruby api ruby-on-rails-5 rails-api


    【解决方案1】:

    我认为您可以进一步优化查询,但这应该可以通过 user_id 加入 User 和 Stat ang 分组。

    在控制器中:

    @users = User.joins(:match_stats)
                 .group('users.id')
                 .select("users.name AS name, SUM(match_stats.points) as tot_points, COUNT(DISTINCT match_stats.match_id) AS tot_matches, (SUM(match_stats.points)/COUNT(DISTINCT match_stats.match_id)) AS average_points_per_match")
                 .order("average_points_per_match DESC")
                 .limit(10)
    

    并且在视图中(非常基本):

    <% @users.each do |user| %>
      <p><%= user.name %> | <%= user.tot_points %> | <%= user.tot_matches %> | <%= user.average_points_per_match %></p>
    <% end %>
    

    【讨论】:

      【解决方案2】:

      从用户的所有统计数据中获取用户的总分:

      user_sum_points = user.stats.map(&:points).compact.sum
      

      我不太确定您要的第二个数字是多少。您是否打算除以用户参加的比赛总数?如果是这样,那么您可以计算其匹配项的唯一 ID:

      user_num_matches = user.stats.map(&:match_id).uniq.length
      

      最后,做除法:

      (user_sum_points / user_num_matches) unless user_num_matches == 0
      

      【讨论】:

        【解决方案3】:

        我的旧代码:

        stat= section
            .group(:user_id)
            .select("user_id, count(*) as matches_count, sum(points) as score")
            .where.not(match_id: nil)
        

        转向这个:

        stat= section
            .group(:user_id)
            .select("user_id, COUNT(DISTINCT match_id) as matches_count, sum(points) as score")
            .where.not(match_id: nil)
        

        通过使用COUNT(DISTINCT match_id) 而不是COUNT(*) 解决了这个问题。谢谢!归功于:@Ovidiu Toma

        【讨论】:

          猜你喜欢
          • 2013-12-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-21
          • 2012-04-04
          • 2017-12-10
          • 1970-01-01
          相关资源
          最近更新 更多