SQL Query Math Gymnastics - PullRequest
       5

SQL Query Math Gymnastics

3 голосов
/ 22 апреля 2010

У меня есть две таблицы проблем: users и race_weeks. Пользователь имеет много race_weeks, и race_week принадлежит пользователю. Следовательно, user_id - это fk в таблице race_weeks.

Мне нужно выполнить сложную математику для полей в таблице race_weeks, чтобы вернуть пользователям наибольшее количество очков за все время.

Вот поля, которыми мы должны манипулировать в таблице race_weeks.

races_won (int)
races_lost (int)
races_tied (int)
points_won (int, pos or neg)
recordable_type(varchar, Robots can race, but we're only concerned about type 'User')

Чтобы вы полностью понимали бизнес-логику на работе, в течение недели пользователь может участвовать во многих гонках. Запись race_week представляет итоговые результаты гонок пользователя за эту неделю. Пользователь считается активным в течение недели, если races_won, races_lost или races_tied больше 0. В противном случае пользователь неактивен.

Итак, вот что нам нужно сделать в нашем запросе, чтобы вернуть пользователей с наибольшим количеством выигранных баллов (фактически net_points_won):

  1. Рассчитать net_points_won каждого пользователя (не поле в БД).

  2. Для расчета net_points_won вы берете (1000 * count_of_active_weeks) - сумму (points__won). (Почему 1000? Просто представьте, что каждую неделю пользователь получает 1000 баллов за участие в соревнованиях и участвует в гонках. Мы хотим вычленить то, что мы увидим, потому что пользователь может участвовать только в одной гонке в неделю за 100 баллов и быть сидя на 900, который мы бы исказили, кто на самом деле заработал наибольшее количество очков.)

Это немного запутанно, поэтому дайте мне знать, если я смогу уточнить.

Ответы [ 2 ]

0 голосов
/ 22 апреля 2010

Я полагаю, что ваша бизнес-логика неверна: net_points должно быть суммой очков, выигранных для этого пользователя, минус количество очков, которые пользователь заметил.

Кроме того, проверка активных недель должна явно проверять races_won, races_lost и races_tied на ноль, чтобы дать системе возможность использовать индексы для этих столбцов, когда таблица становится большой.

SELECT user_id
     , SUM(points_won) - 1000 * COUNT(*) AS net_points
  FROM race_weeks
 WHERE recordable_type = 'User'
   AND (races_won > 0 OR races_lost > 0 OR races_tied > 0)
 GROUP BY user_id
 ORDER BY net_points DESC
0 голосов
/ 22 апреля 2010
SELECT  user_id, 1000 * COUNT(*) - SUM(points_won) AS net_points
FROM    race_weeks
WHERE   races_won + races_lost + races_tied
        AND recordable_type = 'User'
GROUP BY
        user_id
ORDER BY
        net_points DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...