检查用户是否已投票支持他可以投票的最大项目数

时间:2013-05-22 11:19:18

标签: php mysql sql

items

id  maxVotes    parent      type
10  2           9           heading 
11  0           10          item
12  0           10          item

votes

userId  votedFor parent
1       11       10 
1       12       10
2       12       10

我试图检查项目是否存在,以及用户是否已投票支持该标题下允许的最大项目数。

在上面的示例中,表items包含项目。表votes包含用户投票的投票。

items type : heading指定用户可以为col : maxVotes投票的最大项目数。在这种情况下,它是2

votes user 1已对2个项目进行了投票,并且不再对该标题下的items投票。用户2可以再投票1件。

它继续这样。

我目前的方式(使用php)是:

select id, parent from items where id = 11 //The item exists.

select maxVotes from items where id = parent // This gives me the maximum items a user can vote for.

select count(votedFor) as votes from votes where userId = 1 // This'll give me 2.

User 1 can vote no more, but user 2 can vote once more -> Add his vote to the votes table

除了我上面的方式之外,您能想到一种更简单,更有效和更复杂的方法吗?

我可以对事情进行更改,因为这仍然没有实现。或者,这是最好的方式吗?

2 个答案:

答案 0 :(得分:2)

您的设计没问题,您可以在一个查询中合并所有步骤。

SELECT 
userId
FROM votes
# WHERE NOT EXISTS (SELECT 1 FROM votes sv WHERE sv.userId = votes.userId
#                   AND votedFor = 11)
GROUP BY userId
HAVING COUNT(*) < (
  SELECT
  MAX(i2.maxVotes)
  FROM
  items i1
  INNER JOIN items i2 ON i1.parent = i2.id
  WHERE
  i1.id = 11 /*Here you choose which item*/
)

此查询将为您提供仍可投票的用户。取消注释WHERE NOT EXISTS部分,以排除尚未达到投票限制但已投票支持您正在检查的项目的用户。

看到它在sqlfiddle中正常工作。

<强>更新

SELECT 
CASE WHEN numberOfVotes >= maxVotesForItem THEN 'Has reached vote limit'
     ELSE CONCAT('User has ', maxVotesForItem - numberOfVotes, ' vote left')
END AS result
/*optionally include...*/
#, numberOfVotes, maxVotesForItem
FROM (
  SELECT
  COUNT(*) AS numberOfVotes
  , (SELECT
     MAX(i2.maxVotes)
     FROM
     items i1
     INNER JOIN items i2 ON i1.parent = i2.id
     WHERE
     i1.id = 11 /*Here you choose which item*/
  ) AS maxVotesForItem
  FROM
  votes
  WHERE 
  userId = 2 /*Here you choose which user*/
) sq

再次sqlfiddle

答案 1 :(得分:0)

您可以通过添加一个字段voteCount来更改表结构,并将voteFor存储在json结构中,如下所示,

Table: UserVote

userId  voteCount voteFor
1       2         {11,12}
2       1         {11}

因此,在投票时,您可以在此表中插入计数,并从此处检查投票计数。

(OR)

再添加一个表和2个表作为仅有计数的voteCount

Table: VoteCount

userId  voteCount
1       2        
2       1        


Table items

id  maxVotes    parent      type
10  2           9           heading 
11  0           10          item
12  0           10          item

Table votes

userId  votedFor
1       11
1       12
2       12

第一种方法是高效的,它减少了一个表。易于更新。从DB中检索json数据对其进行解码。向该数组添加一个id。编码并更新它。多数民众赞成。