具有排名变量的row_number不起作用

时间:2014-09-12 09:49:27

标签: mysql ranking row-number

我想获得游戏系统中玩家的排名,但我无法正确使用@rank变量。这里的问题在哪里?

第一张桌子:'玩家'

+----+----------+--------+
| id | name     | points | 
+----+----------+--------+
| 1  | Player 1 |   100  |
| 2  | Player 2 |   250  |
| 3  | Player 3 |    57  |
| 4  | Player 4 |   578  |
| 5  | Player 5 | 12580  |
+----+----------+--------+

第二张桌子:'公会'

+----+------------+
| id | name       |
+----+------------+
| 1  | FirstClass |
+----+------------+

第三张桌子:'guild_player_cross'

+----+----------+-----------+
| id | guild_fk | player_fk | 
+----+----------+-----------+
| 1  | 1        | 2         |
+----+----------+-----------+

现在我希望按球员的积分排列球员排名列表。

查询声明:

SELECT 
    @rank := @rank + 1 AS rank,
    p.name,
    p.points,
    g.name AS guild
FROM player AS p
LEFT JOIN guild_player_cross AS gp ON p.id = gp.player_fk
LEFT JOIN guild AS g ON gp.guild_fk = g.id
INNER JOIN (
    SELECT @rank := 0
) AS tblRank
ORDER BY p.points DESC

但结果不是我想的,因为排名数字不正确。:/

结果:

+------+----------+--------+-------------+
| rank | name     | points | guild       | 
+------+----------+--------+-------------+
| 5    | Player 5 | 12580  | NULL        |
+------+----------+--------+-------------+
| 4    | Player 4 |   578  | NULL        |
+------+----------+--------+-------------+
| 1    | Player 2 |   250  | FirstClass  |
+------+----------+--------+-------------+
| 2    | Player 1 |   100  | NULL        |
+------+----------+--------+-------------+
| 3    | Player 3 |    57  | NULL        |
+------+----------+--------+-------------+

3 个答案:

答案 0 :(得分:1)

在添加排名后执行排序,

试试这个:

SELECT 
    @rank := @rank + 1 AS rank,
    x.*
FROM (
SELECT
    p.name,
    p.points,
    g.name AS guild
FROM player AS p
LEFT JOIN guild_player_cross AS gp ON p.id = gp.player_fk
LEFT JOIN guild AS g ON gp.guild_fk = g.id
INNER JOIN (
    SELECT @rank := 0
) AS tblRank
ORDER BY p.points DESC) x

答案 1 :(得分:0)

您可以尝试此查询:

SELECT 
   @rank := @rank + 1,
    p.name,
    p.points,
    ( 
        SELECT g.name 
        FROM guild_player_cross AS gp 
        LEFT JOIN guild AS g ON gp.guild_fk = g.id 
        WHERE p.id = gp.player_fk
    ) AS guild
FROM player AS p
INNER JOIN (
    SELECT @rank := 0
) AS tblRank
ORDER BY p.points DESC;

我已将联接放入子查询中,以免干扰订单。

我希望你有所帮助

答案 2 :(得分:0)

这是一种没有变量的替代方法。在许多需要排名的情况下,这将提供更好的性能。

SELECT FIND_IN_SET(points, points_list) AS rank, p.name, p.points, g.name AS guild
FROM player AS p
CROSS JOIN (SELECT GROUP_CONCAT(DISTINCT points ORDER BY points DESC) AS points_list FROM player) points_list
LEFT JOIN guild_player_cross AS gp ON p.id = gp.player_fk
LEFT JOIN guild AS g ON gp.guild_fk = g.id
ORDER BY rank