Таблица лидеров, запрос ранга, как вернуть строки выше / ниже ранга пользователя
Учитывая этот запрос, если я хочу вытащить ранг конкретного человека, где я знаю, что есть $name и $score, и вернуть строки выше / ниже этого ранга (скажем, + / - 4), Как я буду это делать?
$query = "SELECT @curRank := @curRank + 1 AS Rank,
uniqueID,
name,
score
FROM scores, (SELECT @curRank := 0) r
ORDER by score DESC";
Я пишу на php, используя MySQL и C# в Unity. Моя игра делает звонок на сервер и запускает php-код. Цель состоит в том, чтобы повторить информацию и проанализировать информацию обратно в игре.
Любая помощь будет очень признательна :)
1 ответ:
Основываясь на вашем
:=
, я предполагаю, что вы используете PostgreSQL, правильно? Я больше знаком с синтаксисом T-SQL; но, несмотря на это, и PostgreSQL, и T-SQL имеют оконные функции. Вы можете реализовать что-то похожее на следующее (Я оставил переменные для заполнения):Пояснение: во-первых, мы создаем общее табличное выражение под названием$query = "WITH scoreOrder AS ( SELECT uniqueID, name, score, ROW_NUMBER() OVER (ORDER BY score DESC, uniqueID DESC) AS RowNum FROM scores ORDER BY uniqueID DESC ) SELECT ns.* FROM scoreOrder ms --Your matching score INNER JOIN scoreOrder ns --Your nearby scores ON ms.name = /* your name variable */ AND ms.score = /* your score variable */ AND ns.RowNum BETWEEN ms.RowNum - /* your offset */ and ms.RowNum + /* your offset */";
scoreOrder
и проектируем столбецRowNum
для ваших оценок. Короче говоря,ROW_NUMBER() OVER (ORDER BY score DESC, uniqueID DESC)
просто говорит: "Я возвращаю номер строки эта запись заказанаscore
иuniqueID
, как по убыванию, так и в таком порядке.- Тогда ты присоединишься к этому CTE вместе с ним самим...ms
будет ваш счет, который вы сопоставляете, и вы соединяете , который Сns
, гдеns.RowNum
будет между вашимms.RowNum
, плюс или минус ваше смещение. Существует масса других оконных функций. Вот некоторые другие, которые могут быть более или менее подходящими для вашего сценария:
ROW_NUMBER()
- номер строки записьRANK()
- ранг записи, дублирующейся в связях и включающей пробелы (то есть, если 2-е место связывает, у вас будет 1-е, 2-е, 2-е, 4-й )DENSE_RANK()
- то же, что и Ранг, за исключением того, что он заполняет пробелы (то есть, если 2-е место связывает, у вас будет 1-е, 2-е, 2-е, 3-е)Для получения дополнительной информации, проверьте документацию PostgreSQL по оконным функциям и их учебник
Обновление:
К сожалению, MySQL не поддерживает оконные функции или общие табличные выражения. В вашем сценарии вам придется поместить результаты предыдущего запроса во временную таблицу, а затем выполнить аналогичное объединение, как показано выше. Так, например...
CREATE TEMPORARY TABLE IF NOT EXISTS allRankings AS ( SELECT @curRank := @curRank + 1 AS Rank, uniqueID, name, score FROM scores, (SELECT @curRank := 0) r ORDER by score DESC, uniqueID ); SELECT r.* FROM allRankings r INNER JOIN allRankings myRank ON r.Rank BETWEEN myRank.Rank - <your offset> AND myRank.Rank + <your offset> AND myRank.name = <your name> AND myRank.score = <your score> ORDER by r.Rank;
Вот ссылка SQLFiddle для примера. (я не использую временную таблицу на SQLFiddle, потому что вам нужно построить таблицы в окне схемы сборки).