Пересчет рангов после того, как за каждый элемент проголосовали - PullRequest
2 голосов
/ 15 января 2012

У меня есть таблица предметов, за которые пользователи могут голосовать. В этой таблице есть столбец 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].

Как я могу включить связи, как я описал выше?

Ответы [ 4 ]

1 голос
/ 15 января 2012

Я бы не стал сохранять ранг в базе данных.Вы можете рассчитать его, показывая результат.

$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
}
0 голосов
/ 18 января 2012

Действительно зависит от размера таблицы и частоты обновления, но как насчет триггера? MySQL - рейтинг обновления триггера

0 голосов
/ 15 января 2012

Нет экземпляра 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

Выясните особый набор "голосов", закажите их, дайте каждому число, а затем используйте его дляпривязать число (ранг) к каждому голосованию.

0 голосов
/ 15 января 2012

Это не элегантное решение вернет то, что вы хотите:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...