Привет, сообщество StackOverflow:
Ситуация
Я создаю запрос на обновление, который устанавливает ранги для всех записей в таблице в соответствии с тем, как каждая запись сравнивается друг с другом. Пример таблицы:
id | budget | cost | rank | rank_score
1 | 500 | 20 | ? | ?
2 | 400 | 40 | ? | ?
3 | 300 | 40 | ? | ?
Таким образом, в этой таблице cost
имеют наибольший вес при определении ранга, за ними следует budget
. Таким образом, запись № 2 будет иметь более высокий ранг, запись № 3 будет второй, а запись № 1 — последней. Как видите, если две записи имеют одинаковые cost
, то budget
нарушает равенство.
Теперь, чтобы легко отслеживать такой «вес», я создаю столбец rank_score
, который будет содержать конкатенацию cost
и budget
. Таким образом, rank_score
для таблицы выше будет:
id | budget | cost | rank | rank_score
1 | 500 | 20 | ? | 20500
2 | 400 | 40 | ? | 40400
3 | 300 | 40 | ? | 40300
Это rank_score
можно заполнить так:
UPDATE table_name
SET rank_score = CONCAT(cost, budget);
Проблема
Пока все в порядке. Но теперь возникает проблема. Мне нужен столбец rank
, состоящий только из целых чисел, для нескольких вещей, таких как сортировка, но, прежде всего, для показа пользователю ранга его записи. Конечно, этот столбец rank
будет равен порядку убывания rank_scores. Но я не могу найти способ вычислить этот столбец rank
в одном запросе на обновление без необходимости выполнять подзапросы, циклы в php и т. д.
Что я пробовал
Итак, сначала я пытался получить расчет rank_score
, например:
SELECT id,
CONCAT(cost, budget) AS rank_score
FROM table_name ;
а затем зациклить в php все эти rank_scores, только чтобы построить запрос, который выглядел так:
UPDATE table_name
SET rank_score = CASE id WHEN 1 THEN 20500 END,
rank = CASE id WHEN 1 THEN 3 END
WHERE id IN (1) ;
... Конечно, этот пример запроса на обновление не является полным, так как он содержит больше предложений WHEN THEN END
для каждой записи в таблице. Излишне говорить, что это уродливо, особенно когда вы ожидаете, что у вас будут тысячи и тысячи записей.
Итак, в заключение, у меня уже есть способ вычисления rank_score
, но я также хочу вычислить rank
(= порядок убывания рейтинга) в том же запросе или, по крайней мере, без этого сумасшедшего цикла php и предложений CASE WHEN THEN END
.
Спасибо, что читаете и думаете об этом ;)
Уточнения
Уточнение того, что сказал @SJuan76: я не могу присвоить ранг через php, поскольку бывают случаи, когда пользователю будет показано фиксированное количество записей за раз (например, его пользовательская страница: SELECT * WHERE user_id = 333
, которая может получить 1, 3 или 8 записей) и ему нужно знать ранг каждой записи. Присвоение рейтинга через php в этом случае не работает, потому что такой рейтинг будет относиться к выбранным записям, а не ко всем в таблице.