对每个项目进行投票后重新计算排名

Posted

技术标签:

【中文标题】对每个项目进行投票后重新计算排名【英文标题】:Recalculating ranks after each item is voted on 【发布时间】:2012-01-15 00:20:42 【问题描述】:

我有一张允许用户投票的项目表。在这个表中,有一个 votes 列,保存该项目累积的票数,还有一个 rank 列,这是根据他们拥有的票数对所有项目进行排名(即大多数票获得排名 1,第二多获得排名 2,依此类推)

目前,我在每次投票后重新计算每个项目的排名。也就是说,当用户投票时,我在该项目的 votes 列中添加一个,然后使用以下查询更新每个排名:

SET @rank = 0
UPDATE items SET rank = @rank := @rank + 1 ORDER BY votes DESC

这在大多数情况下都有效,但不考虑投票关系。如果我有投票 [10, 4, 3, 0],我希望排名 [1, 2, 3, 4]。但是,如果我有投票 [10, 10, 3, 0],我想要排名 [1, 1, 3, 4]。这不会发生;我仍然获得排名[1, 2, 3, 4]

我怎样才能像上面描述的那样合并关系?

【问题讨论】:

【参考方案1】:

我不会将排名保存在数据库中。您可以在显示结果的同时计算它。

$rank = 1;
$lastVotes = -1;
$lastAdd = 0;

$query = mysql_query("SELECT * FROM table WHERE * ORDER BY votes DESC", $link);
while( $row = mysql_fetch_array( $query ) ) 
  // local variable with votes
  $votes = $row['votes'];

  // check if we have a tie
  if( $lastVotes == $votes ) 
    // don't change rank if there is a tie but inc $lastAdd
    $lastAdd += 1;
   else 
    // there is no tie: save last votes, adjust $rank and reset $lastAdd
    $lastVotes = $votes;
    $rank += $lastAdd;
    $lastAdd = 1;
  

  // $rank is your rank

【讨论】:

+1 表示“我不会将排名保存在数据库中”。当您将聚合值或计算值保存在另一列中时,它们不同步的机会比比皆是。但是,有一些案例,它们通常与性能有关。在这些情况下,触发器和/或单独的表可能是合适的。此类性能问题需要分析使用情况。【参考方案2】:

这个不优雅的解决方案会返回你想要的:

update ITEMS I1
   set rank =
         (select count(*)
            from ITEMS I2
           where I2.VOTES >= I1.VOTES)
         - (select count(*) - 1
              from ITEMS I3
             where I3.VOTES = I1.VOTES)

【讨论】:

这很好用,只是它似乎没有更新数据库中的排名数据;它只返回每一行的新排名。【参考方案3】:

没有 mysql 实例可以尝试这个,但是像这样的东西怎么样:

    SELECT v.id, v.votes, r.rank
      FROM votes v
          ,(SELECT votes, @rownum = @rownum + 1 AS rank
              FROM votes
              GROUP BY votes
              ORDER BY votes DESC
           ) r
      WHERE v.votes = r.votes
      ORDER BY rank

找出不同的“投票”集合,对它们进行排序,给每个人一个数字,然后用它来将数字(排名)与每个投票相关联。

【讨论】:

哦,我应该补充一点,排名是一个计算值,我也绝对不会将它存储在数据库中。【参考方案4】:

确实取决于表大小和更新频率,但是触发器呢? MySQL- Trigger updating ranking

【讨论】:

以上是关于对每个项目进行投票后重新计算排名的主要内容,如果未能解决你的问题,请参考以下文章

根据百分比查询投票表顶部项目

如何计算每个项目的平均指数位置

投票系统

jaee课程设计

DBA投票项目回顾——定位蓝海的LOTS

什么是对列表重新排序进行动画处理的 react.js 友好方式?