如果用户在MySQL表中投票,则计算投票数

时间:2013-03-20 03:14:35

标签: mysql sql

我有3个MySQL表:

功能表:

id    name
----------
 1    feature 1
 2    feature 2
 3    feature 3
 4    feature 4
 5    feature 5

投票表:

userid featureid
----------------
1       1
1       2
1       3
1       4
2       1
2       2
2       3
2       4
3       1
3       2
3       3
4       1

用户表:

id  name
--------
 1  John
 2  Alice
 3  Bob
 4  Mark
 5  Jane
 6  Mary
 7  Ann

我需要获取单个查询:

  • 总是所有功能,无论他们是否有选票
  • 每个功能必须只列出一次,无论选票数多少,即使它没有投票
  • 每个列出的功能的投票数
  • 如果当前登录的用户为列表中的当前功能投票,则为特殊标记 - 例如,如果用户3已登录,则列出所有用户的投票计数的所有功能,如果用户3投票支持某些功能,则会有特殊字段指示如果他不这样做他的投票或NULL(必须包括投票表中的其他数据,所以它需要左联)

到目前为止,我做到了这一点:

SELECT *,(SELECT COUNT(*) FROM votes WHERE votes.featureid=features.id) AS "votecnt"
FROM features
LEFT JOIN votes ON votes.featureid=features.id
LEFT JOIN users ON users.id=votes.userid
GROUP BY features.id

它列出了所有功能,但如果用户3投票,则没有特殊字段。我尝试了IF,各种WHERE条件,经过多次尝试......用完了想法。

所需的输出可能如下所示:

features.id  features.name  votes.userid  votes.otherfields  users.id  users.name
     1         feature 1          4             -                4        Mark
     2         feature 2        NULL            -              NULL       NULL
     3         feature 3        NULL            -              NULL       NULL
     4         feature 4        NULL            -              NULL       NULL      
     5         feature 5        NULL            -              NULL       NULL

列出了所有功能,只有用户4投票的功能才能填充其他联接表,其他功能只是NULL。如果其他人投票支持功能2,则它仍为NULL,因为它与用户4无关,因为在此示例中用户4已登录。

问题在于:

http://sqlfiddle.com/#!2/c3d10/3

http://sqlfiddle.com/#!2/c3d10/4

http://sqlfiddle.com/#!2/c3d10/5

http://sqlfiddle.com/#!2/c3d10/6

http://sqlfiddle.com/#!2/c3d10/7

在SQLFiddle中的所有上述查询中,无论userid如何,它都应输出所有5个功能。因此,必须以某种方式修改查询以显示所有功能 - 即使其他人投票支持某项功能,或者如果没有投票或当前用户投票选择功能。

2 个答案:

答案 0 :(得分:1)

我认为您要求返回所有功能,返回所有计数,但只有用户信息才能投票支持该功能。

如果您指定了用户标识

,我会得到您正在寻找的结果
select f.id
, f.name
, u.id
, u.name
, v.votecnt
from features f
left join (select featureid, COUNT(userid) votecnt from votes group by featureid) v on v.featureid = f.id
left join votes v1 on v1.featureid = f.id and v1.userid = 4
left join users u on u.id = v1.userid

我选择在左边的连接中指定用户ID来投票。在其他任何地方,它限制了返回的总行数。

结果:

1   feature 1   4   Mark    4
2   feature 2   NULL    NULL    3
3   feature 3   NULL    NULL    3
4   feature 4   NULL    NULL    2
5   feature 5   NULL    NULL    NULL

“Bob”的例子

select f.id
, f.name
, u.id
, u.name
, v.votecnt
from features f
left join (select featureid, COUNT(userid) votecnt from votes group by featureid)v on v.featureid = f.id
left join votes v1 on v1.featureid = f.id and v1.userid = 3
left join users u on u.id = v1.userid

结果:

1   feature 1   3   Bob 4
2   feature 2   3   Bob 3
3   feature 3   3   Bob 3
4   feature 4   NULL    NULL    2
5   feature 5   NULL    NULL    NULL

答案 1 :(得分:1)

这应该这样做:

SELECT tmp1.id, name, votecnt, user_id, user_name FROM 
(SELECT *,(SELECT COUNT(*) FROM votes WHERE votes.featureid=features.id) AS "votecnt" FROM features) as tmp1
LEFT JOIN (SELECT features.id as feature_id, users.id as user_id, users.name as user_name FROM features
JOIN votes ON votes.featureid=features.id
JOIN users ON users.id=votes.userid
WHERE users.id=3) as tmp2 on tmp1.id = tmp2.feature_id

可能它不是最漂亮的sql,而且很可能还有优化空间