Система рейтинга: Как выбрать следующий элемент, за который пользователь еще не голосовал - PullRequest
1 голос
/ 01 апреля 2012

У меня есть 3 таблицы со следующими столбцами:

* users : user_id
* votes : user_id, creation_id
* creations : creation_id, creation_points

Каждый user может голосовать один раз за каждый creation.Когда пользователь голосует, это происходит:

  • Таблица votes: вставить новую строку с user_id и creation_id (чтобы мы могли проверить, голосовал ли уже пользователь за это создание)
  • Таблица creations: добавить +1 к строке creation_points для соответствующего создания

Но теперь я хочу, чтобы, когда пользователь успешно проголосовал за создание, он отображал его следующее создание, за которое он еще не голосовал.Как мне этого добиться?

Я пробовал следующим образом:

  1. Выберите следующий creation_id из таблицы creations (где creation_id больше, чем текущий creation_id)
  2. Проверьте, существует ли уже пара creation_id & user_id в таблице votes.Если он существует, повторите попытку с 1).

Проблема этого метода заключается в том, что ему нужно много запросов, если пользователь уже проголосовал за следующее создание.Это также создает бесконечный цикл, если он уже проголосовал за все творения.Есть ли другие альтернативы?

Ответы [ 2 ]

2 голосов
/ 01 апреля 2012

Если я понимаю, как вы справляетесь с этим, вы, кажется, на правильном пути, сохраняя votes как user_id и creation_id. Чтобы получить следующее доступное создание, используйте запрос LIMIT 1, который исключает уже одобренные создания:

Этот метод использует NOT IN() подзапрос:

SELECT 
 creations.*
FROM creations 
WHERE creation_id NOT IN (
  SELECT creation_id FROM votes WHERE user_id = <the user_id>
)
ORDER BY creation_id ASC 
LIMIT 1

Аналогичная вещь, использующая NOT EXISTS вместо:

SELECT 
 creations.*
FROM creations 
WHERE NOT EXISTS (
  SELECT creation_id 
  FROM votes 
  WHERE 
   user_id = <the user_id>
   AND creations.creation_id = votes.creation_id
)
ORDER BY creation_id ASC 
LIMIT 1
0 голосов
/ 01 апреля 2012

вы можете объединиться в таблице голосов

, если ваш текущий creation_id = 123456

ваш идентификатор пользователя = 789

SELECT c.creation_id 
FROM creations AS c 
INNER JOIN votes AS v ON v.creation_id = c.creations_id 
WHERE c.creation_id > 123456 AND v.user_id != 789 
ORDER BY c.creation_id ASC 
LIMIT 0,1
...