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


MySQL select statement - How to calculate the current ranking

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

要澄清的示例:

  • 排名NR,用户名,投票,
  • 1、
  • 名称1、18次
  • 2、名称1、16倍
  • (我的排名在这里(,我的名字,13次

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

现在,我可以通过PHP中的递增$i轻松显示排名数字。但我只想显示一个仅限于十个用户的列表(前十名列表(,紧接着我目前的排名,如果我还没有进入前十名。所以我只是想知道如何使用MySQL获得我的确切排名数字。我假设此列表中有数百个用户具有不同数量的选票。

这是我目前的声明:

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

我不能给你确切的代码,但我认为以下内容可以给你一些想法

从中选择"排名-NR"、"用户名"、"投票"(选择"RANK-NR"、"USERNAME"、"VOTED"、RANK(( OVER(按"voted"desc 排序(作为 rank 从users_ranking哪里 uid ='".$_SESSION['uid']."和WEEKOFYEAR( date (=WEEKOFYEAR(NOW(((( 饰演 ABC哪里名次<11

我认为 rank(( 结束(排序依据<>(应该可以工作

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

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

好的,示例与我的评论一起。你所拥有的通常会起作用,但是没有什么可以强迫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
避免

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

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

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

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