-1

我有 2 个 SQL Server 表:

Players (
    PlayerID INT,
    Name VARCHAR(50),
    Money INT
)
Game (
    GameID INT,
    PlayerID INT
)

我需要进行查询,列出每场比赛中钱最多的玩家。最好的方法是什么?

我认为它应该是这样的逻辑:

foreach(games)
{
   playersInGame = GetPlayersInGame()   
   return playerWithMostMoney from playersInGame
}

但我在 TSQL 方面很糟糕。

4

2 回答 2

4

使用 SQL 时,您希望使用joinandgroup by操作来完成在其他语言中使用循环完成的工作。SQL 比此类语言有很多优势,特别是因为优化器可以从多种实现逻辑的方式中进行选择。例如,SQL 引擎可以利用多个处理器,这在过程语言中是很困难的。

在您的情况下,逻辑有两个部分。第一种是将牌桌连接在一起,这为您提供了所有玩家的金额。第二是找到最好的。为此,我将使用窗口函数max()来获得最大金额(我经常使用row_number()它,但我认为max()更容易解释):

select g.gameid, p.playerid, p.money
from (select g.gameid, p.playerid, p.money,
             max(p.money) over (partition by g.gameid) as MaxMoneyPerGame
      from games g join
           players p
           on g.playerid = p.playerid
     ) gp
where gp.money = gp.maxmoney;

该表达式max(p.money) over (partition by g.gameid)正在计算每个游戏的最大金额(基于partition by子句)。最后一个where条款是选择金钱与最大值匹配的玩家。

请注意,如果两个玩家的最大值相同,他们都会被选中。 row_number()是一种总是只选择一个玩家的替代方案,即使存在具有相同最大金钱价值的重复玩家。

于 2013-07-12T19:45:57.603 回答
3

类似于戈登的回答,但使用rank

select gameid, playerid, money
from (select g.gameid, p.playerid, p.money,
             rank() over (partition by g.gameid order by p.money desc) rn
      from games g 
      join players p on g.playerid = p.playerid
     ) sq
where rn=1
于 2013-07-12T19:56:06.553 回答