Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在对每个项目进行投票后重新计算排名_Mysql_Sql_Database - Fatal编程技术网

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

Mysql 在对每个项目进行投票后重新计算排名,mysql,sql,database,Mysql,Sql,Database,我有一个允许用户投票的项目表。在该表中,有一个投票列,该列保存该项目累计的投票数,还有一个排名列,该列根据所有项目的投票数对所有项目进行排名(即大多数投票获得排名1,第二名获得排名2,等等) 目前,我正在重新计算每次投票后每个项目的排名。也就是说,当用户投票时,我会在该项目的投票列中添加一个,然后使用以下查询更新每个排名: SET @rank = 0 UPDATE items SET rank = @rank := @rank + 1 ORDER BY votes DESC 这在很大程度上是可

我有一个允许用户投票的项目表。在该表中,有一个
投票
列,该列保存该项目累计的投票数,还有一个
排名
列,该列根据所有项目的投票数对所有项目进行排名(即大多数投票获得排名1,第二名获得排名2,等等)

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

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]


我怎样才能像上面描述的那样合并领带?

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

$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
}

这种不雅观的解决方案会返回您想要的结果:

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)

没有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

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

实际上取决于表格大小和更新频率,但触发器如何

哦,我应该补充一点,秩是一个计算值,我绝对不会将其存储在数据库中。这非常有效,只是它似乎不会更新数据库中的秩数据;它只返回每行的新排名。+1表示“我不会将排名保存在数据库中”。当您在另一列中保存聚合值或计算值时,它们可能会失去同步。然而,也有这样的案例,它们通常与性能有关。在这些情况下,可以使用触发器和/或单独的表。此类性能问题需要对使用情况进行分析。