В чем суть вопроса ?
На сайте есть топ пользователей по рефералам первого уровня.
То есть составляется топ у кого больше рефералов среди других участников проекта.
Топ участников рассчитывается до 100 пользователей, а место занимаемое в топе для любого пользователя, хоть даже если ты на 100000 месте.
У меня есть таблица
users (
id int primary key,
username varchar index,
referer varchar index,
rating float index,
referals int
)
В таблице users есть поле referals которые постоянно обновлялось когда заходишь на сайт, то это рефералы первого уровня пользователя.
Топ пользователей и позиция человека в этом топе рассчитывалась вот так.
Сначала берем кол-во рефералов пользователя.
SELECT `referals` FROM `tb_users` WHERE `id` = 1
А потом высчитываем позицию.
SELECT COUNT(`tb_users`.`id`) as `row_number` FROM `tb_users`
WHERE `referals` >= 896 ORDER BY `referals` DESC, `tb_users`.`id` ASC
Получаем топ 100.
SELECT
`tb_users`.`id`, `tb_users`.`username`, `tb_users`.`rating`, `tb_users`.`referals`
FROM `tb_users`
ORDER BY `tb_users`.`referals` DESC, `tb_users`.`id` ASC LIMIT 0, 100
Чем мне не нравится данный подход ?
Тем что постоянно надо поддерживать актуальность данных, то есть постоянно когда человек заходит на сайте мы считаем кол-во рефералов и записываем в таблицу, можно конечно и кроном считать, тогда всегда данные будут актуальны.
Также данный запрос не гарантирует твоего места в топе, потому что могут у два или 3 и более пользователя иметь одинаковое кол-во рефералов, да можно добавить проверку на соответствие id пользователя.
Я решил убрать поле `referals` из users и высчитывать его каждый раз для пользователя. Да может это не будет быстро работать потому что нету индекса.
В users около 100к записей.
Я решил сделать новый запрос и высчитать позицию
SELECT COUNT(`tb_users`.`id`) as `row_number`, count(`t1`.`id`) AS `referals`
FROM `tb_users`
LEFT JOIN `tb_users` `t1` ON `t1`.`referer` = `tb_users`.`username`
GROUP BY `tb_users`.`id`
HAVING `referals` >= 895
ORDER BY `referals` DESC, `tb_users`.`id` ASC
Но не понимаю как высчитать позицию пользователя, row_number совпадает с referals.
Что я делаю не так ?
Хочу составить топ пользователей и высчитать позицию его.