Использование SQL для агрегирования и вычисления статистики - PullRequest
1 голос
/ 26 сентября 2011

У меня есть игра-стрелялка, в которой пользователи соревнуются друг с другом в течение недели, чтобы набрать наибольшее количество очков.Я хочу написать запрос, который объединяет статистические данные из таблицы снимков.Здесь представлены следующие таблицы и взаимосвязи:

  • у пользователя много соревновательных_периодов
  • соревновательный_период принадлежит пользователю
  • соревновательный_период имеет много снимков
  • снимок принадлежитto Competition_period

В таблице выстрелов у меня есть следующие поля для работы:

  • result -> строковые значения: WON, LOST или TIED
  • amount_won -> целочисленные значения: например, -100, 0, 2000 и т. д.

Для каждого пользователя я хочу вернуть набор результатов со следующей агрегированной статистикой:

  • won_count
  • lost_count
  • tied_count
  • total_shots_count (won_count + lost_count + tied_count)
  • total_amount_won (сумма суммы_won)
  • avg_amount_won_per_shot (total_amount_won / total_shots_count)

Я работал над этим запросом уже несколько часов, но не добился большого прогресса.Статистические функции меня сбивают с толку.Друг предложил мне попытаться вернуть результаты в новой виртуальной таблице с именем shot_records.

1 Ответ

5 голосов
/ 26 сентября 2011

Вот базовое решение, вычисляющее статистику по всем броскам для данного игрока (вы не указали, хотите ли вы их для каждого периода соревнования или нет):

 SELECT user, SUM(IF(result = 'WON', 1, 0))  AS won_count, 
              SUM(IF(result = 'LOST', 1, 0)) AS lost_count, 
              SUM(IF(result = 'TIED', 1, 0)) AS tied_count, 
              COUNT(*)                       AS total_shots_count, 
              SUM(amount_won)                AS total_amount_won, 
              (SUM(amount_won) / COUNT(*))   AS avg_amount_won_per_shot 
 FROM user U INNER JOIN competition_periods C ON U.user_id = C.user_id
 INNER JOIN shots S ON C.competition_period_id = S.competition_period_id
 GROUP BY user

Обратите внимание, что это включает в себя отрицательные значения при расчете показателя «общая выигранная сумма» (то есть общая сумма уменьшается на потери).Если это не правильный алгоритм для вашей игры, вы должны изменить SUM(Amount) на SUM(IF(Amount > 0, Amount, 0)) в обоих местах, где это происходит в запросе.

...