2

我有 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 中的所有上述查询都应输出所有 5 个功能,而不管用户 ID 是什么。因此,必须以某种方式修改查询以显示所有功能 - 即使其他人投票支持某个功能,或者如果没有投票,或者当前用户投票支持该功能。

4

2 回答 2

2

这应该这样做:

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,而且很可能还有优化的空间

于 2013-03-20T04:41:42.560 回答
1

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

如果您指定用户 ID,我会得到您正在寻找的结果

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

以“鲍勃”为例

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
于 2013-03-20T03:39:07.847 回答