Лучшим подходом, чем одна таблица на вызов, является одна таблица для всех из них. Таким образом, вы можете вычислить общие итоги и индивидуальные рейтинги вызовов по одной таблице. Вы также хотели бы не записывать место напрямую, а вычислять его на лету с помощью соответствующей оконной функции, в зависимости от того, как вы хотите обрабатывать связи (rank()
, dense_rank()
и row_number()
будут иметь разные результаты в этих случаях ); таким образом, вам не нужно постоянно корректировать его при добавлении новых записей.
Таблица примерно такая (Вы не указали базу данных SQL, поэтому я собираюсь предположить Sqlite. Настройте по мере необходимости.):
CREATE TABLE challenge_scores(user_id INTEGER REFERENCES users(id),
challenge_id INTEGER REFERENCES challenges(id),
prize_amount NUMERIC,
PRIMARY KEY(user_id, challenge_id));
позволит вам делать такие вещи, как
SELECT *
FROM (SELECT user_id,
sum(prize_amount) AS total,
rank() OVER (ORDER BY sum(prize_amount) DESC) AS place
FROM challenge_scores
GROUP BY user_id)
WHERE place <= 50
ORDER BY place;
для глобального списка лидеров или аналогичного:
SELECT *
FROM (SELECT user_id,
prize_amount,
rank() OVER (ORDER BY prize_amount DESC) AS place
FROM challenge_scores
WHERE challenge_id = :some_challenge_id
GROUP BY user_id)
WHERE place <= 50
ORDER BY place;
для конкретной задачи.