2014-07-11 5 views
0

Я сейчас пишу систему ранжирования в базе данных. Основная проблема на сайте заключается в том, что запросы SQL ограничены, поэтому я стараюсь писать меньшее количество запросов, даже если это более сложные запросы. На данный момент мой рейтинг таблицы содержит 3 поля, user_id, score и rank. Очевидно, лучший результат означает высокий ранг, вот немного SQL fiddle моих данных.Обновить строку с позицией mysql

CREATE TABLE ranking(user_id INT, score INT, rank INT); 
INSERT INTO ranking(user_id, score, rank) VALUES 
    (1, 150, 1), 
    (2, 120, 3), 
    (3, 130, 2), 
    (4, 100, 5), 
    (5, 110, 4); 

Моя цель состоит в том, чтобы написать запрос, изменить счет (отсюда без проблем), затем установите ранжирование в новое положение, в моей скрипке, если я хочу, чтобы добавить 15 к счету пользователя 4, его счет будет 115, поэтому у него будет лучший балл, который будет у пользователя 5, а его рейтинг теперь должен быть 4, а рейтинг пользователя 5 должен быть 5, возможно ли это сделать с использованием чистого SQL и только в одном (возможно, два) запроса? Я понятия не имею, как построить такой сложный запрос

Редактирование: после некоторых исследований я нашел несколько запросов с помощью SET @rn=0; SELECT @rn:[email protected]+1 AS rankid, но как использовать это в подзапросе, чтобы обновить рейтинг каждого пользователя, затронутого изменением оценки?

+0

Вместо вставки рэнкинг вручную по созданию, почему бы вам не ранжировать их на будущий выбор? Таким образом, он всегда будет учитывать любые обновленные значения. –

+0

@MichaelMcGriff Это хорошая идея, но факт заключается в том, что мне часто приходится проверять, имеет ли пользователь x рейтинг y, и только этот пользователь, поэтому IMO легче проверить ранжирование в базе данных, чем повторно генерировать весь рейтинг каждый раз, когда я хочу проверить ранг конкретного пользователя. Но твоя идея все еще хороша, и я буду использовать ее, если увижу, что ответ на мою проблему слишком сложный. –

ответ

1
UPDATE ranking AS r1 
JOIN (SELECT score AS old_score, score+15 AS new_score FROM ranking WHERE user_id = 4) AS r2 
JOIN (SELECT COUNT(*) AS new_rank FROM ranking 
     WHERE user_id != 4 
     AND score > (SELECT score+15 FROM ranking WHERE user_id = 4)) r3 
SET r1.score = IF(r1.user_id = 4, r2.new_score, r1.score), 
    r1.rank = CASE WHEN r1.user_id = 4 THEN r3.new_rank 
        WHEN (r1.score > r2.old_score) = (r1.score > r2.new_score) THEN r1.rank 
        WHEN r1.score > r2.old_score AND r1.score <= r2.new_score THEN r1.rank + 1 
       END 

DEMO

+0

Вау, именно то, что я искал, спасибо много! –

Смежные вопросы