Таблица лидеров по сумме очков / количеству игр - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть стат модель:

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)

Стат может быть дублирован с одинаковыми user_id и match_id. Мне нужно набрать SUM баллов за каждый user_id, а затем разделить его на число 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 самых высоких указателей.

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Я думаю, что вы можете еще больше уточнить запрос, но это должно сработать, соединив группу User и Stat ang по user_id.

В контроллере:

@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 %>
0 голосов
/ 13 сентября 2018

мой старый код:

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 Тома

0 голосов
/ 12 сентября 2018

Чтобы получить сумму баллов пользователя по всей их статистике:

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

Я не совсем уверен, какой второй номер вы запрашиваете.Планируете ли вы разделить на общее количество матчей, сыгранных пользователем?Если это так, то вы можете подсчитать уникальные идентификаторы их совпадений:

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

Наконец, выполните деление:

(user_sum_points / user_num_matches) unless user_num_matches == 0
...