Система оценок: как выбрать следующий пункт, за который пользователь еще не голосовал

У меня есть 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).

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


person lepix    schedule 31.03.2012    source источник


Ответы (2)


Если я понимаю, как вы с этим справляетесь, вы, кажется, на правильном пути, сохраняя 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
person Michael Berkowski    schedule 31.03.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
person moxy    schedule 31.03.2012