我在对数据库中的球员进行排名时遇到了问题(至少以一种表现良好的方式)。
我有一个存储所有玩家的表格。玩家的等级取决于RankingPoints
的数量。因此,(在最简单的情况下)玩家排名是此表中RankingPoints DESC
排序的位置。
可能有多个玩家拥有相同的RankingPoints
。因此,我需要一个决胜局,以使拥有200.000分的球员排名不会改变。
另一方面,根据球员的性别,年龄和国籍,我有一些子等级。
我该如何实时查看排名?我有一个男球员,来自德国的u18,我想知道他的国家/地区排名。
目前,我有这个针对U18CountryRank的子查询
U18CountryRank = Players // the database-table holding all players
.Where(p => p.Gender == MainPlayer.Gender) // male
.Where(p => p.Country == MainPlayer.Country) // Germany
.Where(p => p.Classification == MainPlayer.Classification) // U18
.Where(p => p.RankingPoints >= MainPlayerRankingPoints) // players better or equal than me
.Where(p => SqlFunctions.Difference(p.PlayerId.ToString(), MainPlayer.PlayerId.ToString()) >= 0) // order by PlayerId
.Count(); // take the number
这是生成的sql:
SELECT
1 AS [C1],
[Project1].[C1] AS [C2]
FROM ( SELECT
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Players] AS [Extent2]
WHERE ([Extent2].[RankingPoints] >= [Extent1].[RankingPoints]) AND ([Extent2].[Gender] = [Extent1].[Gender]) AND ([Extent2].[Country] = [Extent1].[Country]) AND ((DIFFERENCE(LOWER( CAST( [Extent2].[PlayerId] AS nvarchar(max))), LOWER( CAST( [Extent1].[PlayerId] AS nvarchar(max))))) >= 0)) AS [C1]
FROM [dbo].[Players] AS [Extent1]
WHERE (cast('b8957470-db27-4b3c-aa5d-3035ca2c86e6' as uniqueidentifier) = [Extent1].[PlayerId])
) AS [Project1]
对单个玩家来说效果很好。但是当我需要选择某个国家/地区的所有球员时,表现将变得井井有条。
我已经尝试使用View
,它仅选择PlayerId
以及不同的等级。在大型电视机上的表现仍然很糟糕。
另一种方法是在有序子集上使用ROW_NUMBER(但在更大的子集上仍然存在相同的问题)。
针对此类问题的“最佳做法”是什么?
答案 0 :(得分:0)
这是我在MainPlayer
中查找男性,U18,德国的子等级的方法:
var RankOrderedPlayers = Players
.Where(p => p.Gender == MainPlayer.Gender) // male
.Where(p => p.Country == MainPlayer.Country) // Germany
.Where(p => p.Classification == MainPlayer.Classification) // U18
.OrderByDescending(p => p.RankingPoints)
.ThenByDescending(p => p.PlayerId)
.AsEnumerable()
.Select((p, r) => new { Rank = r+1, p });