计算单个行与表的其余部分的等级

时间:2014-07-03 04:59:23

标签: mysql ranking

我有一个用户个人资料表和一个提示表。提示表有一个外键,将用户ID链接到tip.receiver。我需要能够通过收到的提示对用户进行排名。据我了解,MySQL没有RANK()函数。选择多行时,您可以轻松替换,如here所示:

SELECT    id,score,
          @curRank := @curRank + 1 AS rank
FROM      scores p, (SELECT @curRank := 0) r
ORDER BY  score DESC;

但是,我希望能够在选择一行时显示排名。例如,在查看用户的个人资料页面时。我考虑过使用子查询,但是有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

你有几个选择。首先,你可以按照你已经确定的那种不太理想的性能方式来查看子查询方法,即

SELECT
    d.id,
    d.score,
    d.rank
FROM (
    SELECT    
        p.id,
        p.score,
        @curRank := @curRank + 1 AS rank
    FROM      scores p, (SELECT @curRank := 0) r
    ORDER BY  p.score DESC
) d
WHERE d.id = 12345;

或者你可以在users表中添加一个额外的列,然后执行INSERT ... ON DUPLICATE KEY UPDATE来缓存排名值,然后只需从users表中选择与你用户对应的行喜欢。 INSERT查询的示例如下

INSERT INTO usersTable (
    id,
    cachedRank
)
SELECT
    d.id,
    d.rank
FROM (
    SELECT    
        p.id,
        p.score,
        @curRank := @curRank + 1 AS rank
    FROM      scores p, (SELECT @curRank := 0) r
    ORDER BY  p.score DESC
) d
ON DUPLICATE KEY UPDATE
    cachedRank = VALUES(cachedRank);

从长远来看,这将更有效。例如,您可以将其放入存储过程并使用MySQL事件调度程序进行调度。此外,可以将查询调整为INNER JOIN到外部选择中的用户表上,以确保它只更新记录而不是插入任何新记录(在外键不一致的情况下)