Попробуй так...кроме условия score...как ты в коммах пишешь, можно и дату добавить в orderBy...для случаев с одинаковыми...
<?php
$rsUser = Model::where('user_id', ID_ЮЗЕРА)->first();
if($rsUser) {
DB::statement(DB::raw('set @row := 0'));
$rsFirst2Before = Model::where('score', '<=', $rsUser->score)->orderBy('score', 'DESC')->select(['*', DB::raw('@row := @row + 1 as `row`')])->limit(11);
$rsAfter = Model::where('score', '>=', $rsUser->score)->where('user_id', '<>', $rsUser->user_id)->orderBy('score', 'ASC')->select(['*', DB::raw('@row : = @row + 1 as `row`')])->limit(10);
$rs = $rsFirst2Before->union($rsAfter)->get();
// dump($rs);
}
?>
P.S.: В моём ответе подразумевается ещё и порядковый номер в рейтинге среди всех...
Если вообще это работать будет :) Я не тестил, но должно))
Проверяй))
Порядковый номер по ключу
row будет доступен...
UPD:
Ещё немного подправил ответ...там добавил
where('user_id', '<>', $rsUser->user_id), чтобы не было "в последующих 10" одного и того же юзера, если есть с одинаковым рейтингом...
UPD2:
Хотя и тут есть нюанс...если будет, например, 30 юзеров с одинаковым рейтингом...
Короче, если это сработает, дальше разберёмся, чтобы до идеала довести :)
UPD3:
Ещё рассмотрите вариант с временной таблицей...в которую раз в какое-то время (или по событию) сразу записывать юзеров и их места...
По мне так - это самый лучший вариант...