Для правильного вопроса надо знать половину ответа
Для MySQL 8+
UPDATE (
SELECT `id`, ROW_NUMBER() OVER(PARTITION BY `city_id` ORDER BY `rank`) AS `r`
FROM `table`
) AS `t`
JOIN `table` ON `table`.`id` = `t`.`id`
SET `table`.`city_rank` = `t`.`r`
Антон Шелестов, Реально. Только отрабатывать будет дольше.
UPDATE (
SELECT `id`,
(
SELECT COUNT(*)
FROM `table` AS `c`
WHERE `c`.`city_id` = `x`.`city_id` AND `c`.`rank` <= `x`.`rank`
) AS `r`
FROM `table` AS `x`
) AS `t`
JOIN `table` ON `table`.`id` = `t`.`id`
SET `table`.`city_rank` = `t`.`r`