具有排名和独特用户的高分

时间:2016-01-20 13:41:20

标签: c# asp.net sql-server

我想获得一个包含独特用户的Highscore列表。 遇到独特部分的问题。通过删除GROUP BY,脚本不包含错误

数据库:

GameResult
Id, GameId, TicketId,   Score,  Email,          Extra,  CreatedTime
1   1       1           100     test@test.com   info1   2012-12-01T12:12:12
2   1       2           200     test2@test.com  info2   2014-01-01T01:01:01
3   1       3           300     test3@test.com  info3   2013-05-01T05:05:05

Ticket
Id, UserId, TicketNumber,   ControlCode
1   1       abc1            123
2   1       abc2            234
3   2       abc3            345

User
Id, UniqueUserId
1   555
2   666

QUERY:

SELECT 
  g1.*, t1.UserId, t1.ControlCode, t1.TicketNumber, u1.UniqueUserId
FROM [dbo].[GameResult] as g1
INNER JOIN [dbo].[Ticket] as t1
      ON (g1.TicketId = t1.Id)
INNER JOIN [dbo].[User] as u1
    ON (t1.UserId = u1.Id)
GROUP BY u1.UniqueUserId 
ORDER BY g1.Score Desc, g1.CreatedTime Asc

ERROR:

Column 'dbo.GameResult.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

通缉结果:

Rank    GameResult.Id,  GameId, TicketId,   Score,  Email,          Extra,  CreatedTime,            UserId, TicketNumber,   ControlCode,    UniqueUserId
1       3               1       3           300     test3@test.com  info3   2013-05-01T05:05:05     2       abc3            345             666
2       2               1       2           200     test2@test.com  info2   2014-01-01T01:01:01     1       abc2            234             555

3 个答案:

答案 0 :(得分:2)

好的,如果我理解正确,您希望获得每个用户的最高分,并按分数降序返回查询。

在这种情况下,我会使用带有这样的Windows函数的CTE:

(\d{2})

如果有必要,可以在没有CTE和ROW_NUMBER函数的情况下完成所需的操作,但这将是一个更复杂的查询。这是一个更易于阅读的更清洁的解决方案,IMO。

答案 1 :(得分:0)

您只需要在查询中添加rank即可。您可能希望使用dense_rank或row_number,具体取决于您希望如何处理具有相同分数的行。

这是一个模拟查询:

SELECT 
  rank() over (partition by g1.Id order by g1.Score Desc) as Rank,
  g1.Id,
  g1.GameId,
  g1.TicketId,
  g1.Score,
  g1.Email,
  g1.Extra,
  g1.CreatedTime,
  t1.UserId, 
  t1.ControlCode, 
  t1.TicketNumber, 
  u1.UniqueUserId
FROM [dbo].[GameResult] as g1
INNER JOIN [dbo].[Ticket] as t1
    ON (g1.TicketId = t1.Id)
INNER JOIN [dbo].[User] as u1
    ON (t1.UserId = u1.Id)
GROUP BY u1.UniqueUserId 
ORDER BY g1.Score Desc, g1.CreatedTime Asc

提供的排名查询基于示例数据,但很可能您必须计算每个游戏的排名,如下所示:

rank() over (partition by g1.GameId, g1.Id order by g1.Score Desc) as Rank,

答案 2 :(得分:-1)

使用内部联接获取有关SQL join的更多信息 例子

SELECT * FROM GameResult as a 
    INNER JOIN Ticket as b
    ON a.TicketId=b.TicketId;
    INNER JOIN User as c
    ON b.UserId = c.Id