MySQL ограничивает количество строк, используемых для расчета суммы - PullRequest
1 голос
/ 16 апреля 2019

Я делаю игру, в которой счет для игрока рассчитывается каждый час.Счет необходим для того, чтобы доска лидеров могла показывать лучших игроков.«очки», выигранные в игре, сохраняются для игрока в таблицеboards_played.Таблица игроков имеет поле для подсчета очков, которое обновляется ежечасно с помощью этого SQL:

update players p 
       inner join (
          SELECT player_id, sum(points) as total 
            from boards_played
           where time_played > DATE_SUB(now(), INTERVAL 7 DAY)
           GROUP BY player_id) s on p.player_id = s.player_id
  set p.score = s.total

Проблема в том, что тот, кто набирает 50 очков из 100 игр, должен иметь более высокий ранг, чем тот, кто набирает 60 очков из200 игр.

Короче говоря, оценка должна основываться только на последних 100 играх за последние 7 дней.

1 Ответ

1 голос
/ 16 апреля 2019

Вам, вероятно, здесь нужен коррелированный подзапрос, чтобы вы могли получить правильное значение для каждого игрока.

Чтобы найти общий счет определенного игрока, этот подзапрос делает это.

          SELECT SUM(points) as total
            FROM (
                   SELECT player_id, points
                     FROM boards_played
                    WHERE time_played > DATE_SUB(NOW(), INTERVAL 7 DAY)
                     AND player_id = ***something*** 
                    ORDER BY time_played DESC
                    LIMIT 100
                 ) a

Теперь вам нужно включить это в ваш внешний запрос

UPDATE players p
   SET score =
       (
          SELECT SUM(points) as total
            FROM (
                   SELECT points
                     FROM boards_played
                    WHERE time_played > DATE_SUB(NOW(), INTERVAL 7 DAY)
                      AND points.player_id = p.player_id 
                    ORDER BY time_played DESC
                    LIMIT 100
                 ) a
       )

Почему это называется коррелированным? Строка points.player_id = p.player_id в подзапросе соотносит его свнешний запрос.Делая это таким образом, можно LIMIT применять отдельно к очкам каждого игрока.

Но , вам может быть лучше сделать вид, который может вычислить это значение на лету, скореечем обновление таблицы.Тогда вам не нужно постоянно обновлять таблицу.Это будет выглядеть примерно так ( не отлажено ).

CREATE VIEW players_with_score AS
SELECT p.player_id, p.col1, p.col2, p.col3,
       (  
          SELECT SUM(points) as total
            FROM (
                   SELECT points
                     FROM boards_played
                    WHERE time_played > DATE_SUB(NOW(), INTERVAL 7 DAY)
                      AND points.player_id = p.player_id 
                    ORDER BY time_played DESC
                    LIMIT 100
                 ) a
       ) score
  FROM player p 

Тогда вы можете сказать что-то вроде

  SELECT player_id, score
    FROM players_with_score
   WHERE score > 250
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...