评级系统:如何选择用户尚未投票的下一个项目

时间:2012-03-31 22:28:22

标签: mysql sql rating vote

我有3个表格,其中包含以下列:

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

每个user可以为每个creation投票一次。当用户投票时,会发生这种情况:

  • 表格votes:插入一个包含user_idcreation_id的新行(这样我们就可以检查用户是否已投票赞成此创作)
  • creations:为相关创建
  • 的行creation_points添加+1

但是现在,我希望当用户成功投票进行创作时,会向他显示他尚未投票的下一个创作。我怎样才能做到这一点?

我试过这种方式:

  1. creation_id表中选择下一个creations(其中creation_id大于当前creation_id
  2. 检查这对夫妇creation_id& user_id表中已存在votes。如果存在,请从1)重试。
  3. 这种方法的问题在于,如果用户已经投票支持下一次创建,则需要大量查询。如果他已经投票支持所有创作,它也会创造一个无限循环。还有其他选择吗?

2 个答案:

答案 0 :(得分:2)

如果我了解您的处理方式,那么将votes存储为user_idcreation_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

答案 1 :(得分:0)

你可以在投票表上加入

如果您当前的creation_id = 123456

您的用户ID = 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