0

我正在尝试编写一个查询来查找用户游戏的得分排名。我需要它来获取用户 ID,然后将该用户的相对排名返回给其他用户的分数。有一个用户和一个游戏桌。游戏表有一个 userId 字段,具有一对多的关系。

样品表:

用户:
id freebee
1 10
2 13

游戏:
userId 得分
1 15
1 20
2 10
1 15

将 $id 1 传递给此函数应返回值 1,因为用户 1 当前得分最高。同样,用户 2 将返回 2。

目前这就是我所拥有的:

SELECT outerU.id, (

SELECT COUNT( * )  
FROM users userI, games gameI  
WHERE userI.id = gameI.userId  
AND userO.id = gameO.userId  
AND (  
   userI.freebee + SUM(gameI.score)  
   ) >= ( userO.freebee + SUM(gameO.score) )  
) AS rank  
FROM users userO,  
games gameO  
WHERE id = $id

这给了我一个“无效使用组功能”错误。有任何想法吗?

4

5 回答 5

1

该查询不喜欢SUM(gameO.score)相关子查询中 Sum 函数中外部表的引用。其次,停止使用逗号格式进行连接。而是使用 JOIN 的 ANSI 语法。例如,在您的外部查询中,您真的要使用交叉连接吗?这就是您编写的方式以及我在下面的解决方案中如何表示它,但我怀疑这就是您想要的。

编辑

根据您的新信息,我已经调整了我的查询。

Select U.id, U.freebee, GameRanks.Score, GameRanks.Rank
From users As U
    Join    (
            Select G.userid, G.score
                , (
                    Select Count(*)
                    From Games As G2
                    Where G2.userid = G.userid
                        And G2.Score > G.Score
                    ) + 1 As Rank
            From Games As G
            ) As GameRanks
        On GameRanks.userid = U.id
Where U.id =1
于 2010-06-24T15:28:02.123 回答
1
SELECT u.id,total_score,
 ( SELECT COUNT(*) FROM
    (SELECT u1.id, (IFNULL(u1.freebee,0)+ IFNULL(SUM(score),0)) as total_score
     FROM users u1
     LEFT JOIN games g ON (g.userId = u1.id)
     GROUP BY u1.id
    )x1
   WHERE x1.total_score > x.total_score
 )+1 as rank,

( SELECT COUNT(DISTINCT total_score) FROM
    (SELECT u1.id, (IFNULL(u1.freebee,0)+ IFNULL(SUM(score),0)) as total_score
     FROM users u1
     LEFT JOIN games g ON (g.userId_Id = u1.id)
     GROUP BY u1.id
    )x1
   WHERE x1.total_score > x.total_score
 )+1 as dns_rank

 FROM users u

 LEFT JOIN
  ( SELECT u1.id, (IFNULL(u1.freebee,0)+ IFNULL(SUM(score),0)) as total_score
    FROM users u1
    LEFT JOIN games g ON (g.userId = u1.id)
    GROUP BY u1.id
  )x ON (x.id = u.id)

rank- (正常等级 - 例如 - 1,2,2,4,5),dns_rank- 密集等级(1,2,2,3,4)。列total_score- 仅用于调试...

于 2010-06-24T16:07:46.580 回答
0

我不是 MySQL 人,但我相信在其中进行排名的常用方法是在 SQL 语句中使用变量。类似于以下内容(未经测试):

SELECT
    SQ.user_id,
    @rank:=@rank + 1 AS rank
FROM
(
    SELECT
        U.user_id,
        U.freebee + SUM(COALESCE(G.score, 0)) AS total_score
    FROM
        Users U
    LEFT OUTER JOIN Games G ON
        G.user_id = U.user_id
) SQ
ORDER BY
    SQ.total_score DESC

您可以将其用作子查询来获取单个用户的排名,尽管从性能方面来说这可能不是最佳途径。

于 2010-06-24T15:26:12.930 回答
0

这是仅基于“游戏”表计算排名的“简化”版本。为了计算特定游戏的排名,您只需要添加额外的连接。

SELECT COUNT(*) + 1 AS rank
FROM   (SELECT userid,
               SUM(score) AS total
        FROM   games
        GROUP  BY userid
        ORDER  BY total DESC) AS gamescore
WHERE  gamescore.total > (SELECT SUM(score)
                          FROM   games
                          WHERE  userid = 1)  

它基于ranking== number of players with bigger score+ 1的想法

于 2010-06-24T15:47:07.137 回答
0

看看这个: http ://rpbouman.blogspot.com/2009/09/mysql-another-ranking-trick.html

于 2010-10-21T01:52:25.727 回答