MySQL select语句 - 如何计算当前排名

时间:2014-12-10 06:24:17

标签: php mysql select

我有一个名为user_rankings的表,其中为每个用户存储了投票(voted)。我想显示当前用户的排名(本周),这取决于用户获得多少票数。

示例澄清:

  • RANK-NR,USERNAME,VOTED,
  • 1,name1,18次
  • 2,name1,16次
  • (我的排名在这里),myname,13次

在这个例子中,我的排名应该是3.如果我有17票,我就是2号。如果我上面有五个用户,我就是8号。我想你明白了。

现在,我可以使用PHP中的递增$i轻松显示排名编号。但我只想显示一个限制为十个用户的列表(前十个列表),并且直接在我当前的排名之后,如果我还没有进入前十个列表。所以我只是想知道如何使用MySQL获得我的确切排名。 我假设这个列表中有数百名用户拥有不同的投票数。

这是我目前的发言:

SELECT 
`voted`
FROM `users_ranking` 
WHERE 
`uid`='".$_SESSION['uid']."' 
AND 
WEEKOFYEAR(`date`)=WEEKOFYEAR(NOW()) 
LIMIT 1

3 个答案:

答案 0 :(得分:1)

我无法向您提供确切的代码,但我认为以下内容可以为您提供一些想法

选择' RANK-NR',' USERNAME',' VOTED'从 ( 选择                               来自users_ranking 哪里 uid ='" $ _ SESSION [' UID']"' 和 WEEKOFYEAR(date)= WEEKOFYEAR(NOW()) )作为abc 哪里 秩< 11

我认为rank()结束(按<>排序)应该有效

答案 1 :(得分:1)

我刚刚发现自己这个解决方案有效:

SELECT *
FROM 
(
  SELECT  @ranking:= @ranking + 1 rank,
          a.`uid`
  FROM    `users_ranking` a, (SELECT @ranking := 0) b
  ORDER BY a.`votes` DESC
) s
WHERE `uid`='".$_SESSION['uid']."' 
AND 
WEEKOFYEAR(`date`)=WEEKOFYEAR(NOW()) 
LIMIT 1

答案 2 :(得分:1)

好的,举例说明我的评论。你拥有的东西通常会起作用,但是在应用排名之前没有什么可以迫使MySQL进行排序。

因此使用额外级别的子查询会给你(未经测试)。内部子查询以正确的顺序获取相关周的所有用户ID,而下一个外部子查询将排名应用于此有序结果集。外部查询只获取您需要的单个返回行。

SELECT c.rank, c.uid
FROM
(
    SELECT @ranking:= @ranking + 1 rank, a.uid
    FROM 
    (
        SELECT uid, votes
        FROM    `users_ranking`
        WHERE WEEKOFYEAR(`date`) = WEEKOFYEAR(NOW()) 
        ORDER BY votes DESC
    ) a,
    (SELECT @ranking := 0) b
) c
WHERE c.uid = '".$_SESSION['uid']."' 
LIMIT 1

避免子查询并避免变量需求的另一种可能性是进行连接。这是(误)使用HAVING将结果减少到您感兴趣的单行。此解决方案的缺点是,如果多个用户具有相同的分数,则每个用户将获得相同的排名。

SELECT b.uid, COUNT(a.uid) 
FROM users_ranking a
LEFT OUTER JOIN users_ranking b
ON WEEKOFYEAR(a.`date`) = WEEKOFYEAR(b.`date`) 
AND a.votes >= b.votes
GROUP BY b.uid
HAVING b.uid = '".$_SESSION['uid']."' 

修改

排名前10位: -

SELECT b.uid, COUNT(a.uid) AS rank
FROM users_ranking a
LEFT OUTER JOIN users_ranking b
ON WEEKOFYEAR(a.`date`) = WEEKOFYEAR(b.`date`) 
AND a.votes >= b.votes
GROUP BY b.uid
ORDER BY rank
LIMIT 10

虽然在这种情况下使用子查询可能会更快。然后,您可以使用ORDER BY将LIMIT子句放在子查询中,因此只需要使用变量将排名添加到10行。

我不确定如何将其与单个用户的查询相结合,主要是因为我不确定您希望如何将2个结果合并在一起。