【问题标题】:SQL: Get Player Rank In DatabaseSQL:在数据库中获取玩家排名
【发布时间】:2020-01-26 05:40:57
【问题描述】:

我正在为我正在构建的游戏构建高分系统。我认为或者更确切地说希望这是一个容易回答的问题。我需要让玩家对其他玩家进行“排名”。所以假设有 3 名玩家,你的分数最低。所以你的排名是#3。我如何在 SQL 中得到这个?我想我使用COUNT,但我不确定它将如何遍历每一行以找到我的玩家的分数。我知道我会做一个ORDER BY

这是我的基本表:

SELECT [ID]
  ,[Email]
  ,[High_Score]
  ,[Board_Name]
  ,[Difficulty]
  ,[Player_Time]
FROM [Rune_Master].[dbo].[High_Scores]

我需要过滤 Board_NameDifficulty,因为每个棋盘都有 3 个难度,玩家可以在每个棋盘上以 3 种不同的方式排名。最终虽然它是基于他们的High_Score 与其他人相比。对于每个棋盘的每个难度,每个玩家只有 1 分。所以分数会因棋盘+难度而不同。我希望这一切都有意义

这是我目前所拥有的:

--Player Data
DECLARE @PlayerScore AS BIGINT
DECLARE @PlayerRank AS NVARCHAR(100)

IF EXISTS(SELECT [High_Score] FROM [dbo].[High_Scores] WHERE [Board_Name] = @Board AND [Difficulty] = @Difficulty AND [Email] = @Email) BEGIN
    SET @PlayerScore = (SELECT [High_Score] FROM [dbo].[High_Scores] WHERE [Board_Name] = @Board AND [Difficulty] = @Difficulty AND [Email] = @Email)
    SET @PlayerRank = (SELECT TOP 1 COUNT([High_Score]) FROM [dbo].[High_Scores] WHERE [Board_Name] = @Board AND [Difficulty] = @Difficulty ORDER BY [High_Score] DESC)
END ELSE BEGIN
    SET @PlayerScore = 0;
    SET @PlayerRank = 'UnRanked';
END

--Top 5 Player Scores
SELECT DISTINCT TOP 5
    [High_Score] AS [Score],
    [Player_Time],
    [Board_Name],
    [Email],
    @PlayerScore AS 'Player_Score',
    @PlayerRank AS 'Player_Rank'
FROM
    [dbo].[High_Scores]
WHERE
    [Board_Name] = @Board AND
    [Difficulty] = @Difficulty
ORDER BY [High_Score] DESC, [Player_Time] DESC, [Email]

【问题讨论】:

  • 如果是 Microsoft SQL Server(添加相关的 DB 实现作为标签!):ROW_NUMBER() [or DENSE_RANK()] OVER (PARTITION BY.. [ORDER BY..]).
  • 它的 MSSQL Express 服务器,但我不确定我是否理解
  • 查找Partition By
  • ok 所以把这个添加到临时表中,然后从临时表中选择值来获得人员排名?

标签: c# sql .net sql-server


【解决方案1】:

如果有人需要,这里就是答案。谢谢大家的帮助。

代码:

    DECLARE
    @Board AS NVARCHAR(100) = 'Templo_Mayor',
    @Difficulty AS INT = 0,
    @Email AS NVARCHAR(500) = 'Computer',
    @PlayerRank AS NVARCHAR(100)


CREATE TABLE #Rank
(
    High_Score BIGINT,
    Row# BIGINT,
    EMAIL NVARCHAR(500)    
 )
INSERT INTO #Rank (High_Score, Row#, EMAIL) 
SELECT [High_Score], ROW_NUMBER() OVER(ORDER BY [High_Score] DESC) AS Row#, [EMAIL] FROM [dbo].[High_Scores] WHERE [Board_Name] = @Board AND [Difficulty] = @Difficulty ORDER BY [High_Score] DESC

SELECT Row# FROM #Rank WHERE EMAIL = @Email ORDER BY [High_Score] DESC
DROP TABLE #Rank

所以解释一下我做了什么:

  1. 声明了我的变量
  2. 创建了一个临时表,我将用它来构建我的排名表(临时表)
  3. 使用添加行计数器的数据填充我的排名表
  4. 通过那里的电子邮件从我的排名表中选择我的用户的排名,所以我只会返回他们的排名。

【讨论】:

  • 为什么需要临时表?所有这些都可以在一个查询中完成。对填充临时表的 select 语句使用 CTE,然后在选择最终结果集时使用该 cte。不要养成无缘无故应用这种
  • 欢迎分享您的答案。这目前有效,但我想看看您的建议以更好地理解。
猜你喜欢
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 2015-03-01
  • 1970-01-01
相关资源
最近更新 更多