获取每个阶段中每个Summed金额的最大值

时间:2014-07-28 14:52:29

标签: sql sql-server group-by sum max

我搜索了这个网站和其他网站,但无法找到我正在寻找的确切示例。 基本上,我有一个游戏桌(运动,确切地说),需要按用户和舞台总和,然后获得每个阶段的最大值。

这是我的表:

Game_Score_User(GameId, UsrRegId, Stage, Score)
-- Primary key is (GameId, UsrRegId, Stage)

现在,我有不同的GameId,但我只过滤了一次。

然后,对于这个游戏(本例中的篮球),您可以在某个舞台上进行多场比赛。让我们说一个舞台在两天内播放(所以日期并不重要),你在其中播放了6场比赛。您的用户将在播放这些比赛之前输入他们的预测。然后,根据他们成功或失败的预测,他们将获得一些分数。(这是通过一个程序完成的,但我想解释这个表的目的是什么)

好的,现在我们为每个用户提供了某个阶段内的一些分数。因此,如果我们有用户200和用户240,他们可能有这些阶段的分数(取决于他们是否预测该阶段内的任何游戏,否则,他们分别得到该分数或阶段的得分= 0)。

我的理解是,由于你不能做一个MAX(SUM()),你需要在一个查询中解决SUM,然后为它分配一个别名,这样你就可以像使用它一样使用它,然后从那"表"请求所需字段的MAX()值,按正确的字段分组。

我猜测我在子查询中按不必要的值进行分组,但是...如果我不在我的"表&#的子查询中包含这些属性34;使用别名,然后我就不能从"外部"中引用那些属性。或"主要"查询。我怀疑吗?我这样说是因为我收到一个错误,告诉我/那些属性在这种情况下不存在/不存在。

我正在使用SQL Server 2008

底线是我需要在查询结果中获得GameId,UsrRegId,Stage和累积分数,该查询应告诉我 谁赢得每个阶段

我到目前为止所尝试的是以下查询,但它只给了我增加的分数,但不是每个阶段的最大值。即,它只告诉我每个舞台和用户的总数,而不是告诉我"这个用户赢得了这个阶段":

  SELECT JPU.GameId, JPU.UsrRegId, JPU.Stage, MAX(JPU.Score_User) as Winner_Score
  FROM (SELECT GameId, UsrRegId, Stage, SUM(Points) as Score_User
        FROM Game_Score_User
        WHERE GameId = 280 AND
              Stage IN (SELECT Stage
                        FROM Game_Stages 
                        WHERE GameId = 280)
        GROUP BY GameId, UsrRegId, Stage) JPU
  GROUP BY JPU.GameId, JPU.UsrRegId, JPU.Stage

1 个答案:

答案 0 :(得分:0)

好的,让我们回顾一下你的子查询。

SELECT GameId, UsrRegId, Stage, SUM(Points) as Score_User
        FROM Game_Score_User
        WHERE GameId = 280 AND
              Stage IN (SELECT Stage
                        FROM Game_Stages 
                        WHERE GameId = 280)
        GROUP BY GameId, UsrRegId, Stage

stage in (...)实际上并未过滤掉子查询中的任何内容。它实质上是说游戏玩法必须是280并且舞台必须来自具有游戏币280的游戏。如果游戏阶段与gameId不相关,那么它不应该在Game_Score_User表中。换句话说,如果史蒂夫和克里斯没有一起玩任何游戏,我们不应该让约翰尼打赌史蒂夫会击败克里斯。

SELECT GameId, UsrRegId, Stage, SUM(Points) as Score_User
FROM Game_Score_User
WHERE GameId = 280
GROUP BY GameId, UsrRegId, Stage

子查询的这一部分将返回总用户数列表以及与之关联的游戏和阶段。假设此查询返回以下数据:

GameID | UsrRegID | Stage | Score_User
280    | 1        | 1     | 20
280    | 1        | 3     | 4
280    | 2        | 1     | 15
280    | 2        | 2     | 15
280    | 2        | 3     | 15
280    | 3        | 2     | 25
280    | 4        | 1     | 17
280    | 4        | 3     | 12

现在我们需要将此表过滤到每个阶段具有最大score_user的行。你如何接近这个问题的方法是,如果你想撤回GameID,UsrRegId,Stage和Score_User,你不能告诉sql获取max(score_user)并按所有这些列分组。它将取消我上面列出的相同结果。分组将不再帮助解决问题,因为所有数据已经​​正确分组。

不幸的是,真正做到这一点的唯一方法是使用自联接,我们将不得不再次汇总总和以确保我们正在查看的行是最大值。有几种方法可以做到这一点,我个人更喜欢不存在。

SELECT JPU.GameId, JPU.UsrRegId, JPU.Stage, JPU.Score_User as Winner_Score
FROM (SELECT GameId, UsrRegId, Stage, SUM(Points) as Score_User
        FROM Game_Score_User gsu
        WHERE GameId = 280
        GROUP BY GameId, UsrRegId, Stage) gsu
Where not exists (Select *
                    From Game_Score_User gsu2
                    WHERE GameId = 280
                    and gsu2.Stage = gsu.Stage
                    GROUP BY GameId, UsrRegId, Stage
                    Having sum(gsu2.points) > gsu.Score_User)

不存在确保没有任何分数大于当前行。有一种比较聚合函数的方法,在这种情况下,我用它来检查gameid和stage的得分的其他总和。 not exists仅在结果表为空时返回true。此查询应该导致:

GameID | UsrRegID | Stage | Score_User
280    | 1        | 1     | 20
280    | 2        | 3     | 15
280    | 3        | 2     | 25