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表示“我不会将排名保存在数据库中”。当您在另一列中保存聚合值或计算值时,它们可能会失去同步。然而,也有这样的案例,它们通常与性能有关。在这些情况下,可以使用触发器和/或单独的表。此类性能问题需要对使用情况进行分析。