我有一个用户表,其中包含ID,用户名,电子邮件等。
带有id,uid(用户ID),内容等的发布表 带有id,uid,pid(帖子ID),投票(ENUM:'1'和'-1')的
投票表格。
在投票表的投票栏中,1表示投票,-1表示投票。
我希望选择十个帖子,其中包含用户详细信息,不包括upvotes和downvotes。我尝试使用下表,但它不起作用。它为某些ID提供了多余的结果。
select
p.id,
p.uid,
p.post,
u.username,
count(puv.pid) as upvotes,
group_concat(puv.uid) upvoteIds,
count(pdv.pid) as downvotes,
group_concat(pdv.uid) downvoteIds
from
posts p
join
user u ON u.id = p.uid
left join
postvotes puv ON puv.pid = p.id and puv.vote = '1'
left join
postvotes pdv ON pdv.pid = p.id and pdv.vote = '-1'
where
p.deleted = 0
group by u.username , p.created , p.post , p.id , p.uid
order by p.created DESC
limit 0 , 10
查询结果:
+----+-----+--------+----------+---------+-----------+-----------+-------------+
| id | uid | post | username | upvotes | upvoteIds | downvotes | downvoteIds |
+----+-----+--------+----------+---------+-----------+-----------+-------------+
| 19 | 2 | Post 1 | john | 2 | 3,3 | 2 | 1,2 |
| 18 | 1 | Post 2 | dinesh | 2 | 3,1 | 0 | NULL |
| 17 | 3 | Post 3 | sudeep | 0 | NULL | 1 | 3 |
+----+-----+--------+----------+---------+-----------+-----------+-------------+
第一行为 upvoteIds 和 upvotes 提供重复的ID为2.此处,upvotes应为1,因为id为19的帖子只有1个upvote。请查看以下投票表:
+----+-----+-----+------+
| id | pid | uid | vote |
+----+-----+-----+------+
| 1 | 19 | 3 | 1 |
| 2 | 18 | 3 | 1 |
| 3 | 17 | 3 | -1 |
| 4 | 19 | 1 | -1 |
| 5 | 18 | 1 | 1 |
| 6 | 19 | 2 | -1 |
+----+-----+-----+------+
更新
表帖子
+----+-----+--------+
| id | uid | post |
+----+-----+--------+
| 17 | 3 | post 3 |
| 18 | 1 | post 2 |
| 19 | 2 | post 1 |
+----+-----+--------+
答案 0 :(得分:2)
我总是建议从包含最终需要分组的数据的表开始,在这种情况下是postvotes
表。
# upvotes
SELECT puv.pid, count(puv.vote) as upvote
FROM postvotes puv
WHERE puv.vote = 1
GROUP BY puv.pid
这应该为您提供以下数据:
+-----+--------+
| pid | upvote |
+-----+--------+
| 19 | 1 |
| 18 | 2 |
+-----+--------+
# downvotes
SELECT pdv.pid, count(pdv.vote) as downvote
FROM postvotes pdv
WHERE pdv.vote = -1
GROUP BY pdv.pid
这将为您提供以下数据:
+-----+----------+
| pid | downvote |
+-----+----------+
| 17 | 1 |
| 19 | 2 |
+-----+----------+
现在,在一个查询中将它们组合在一起:
SELECT pv.pid, uv.upvote, dv.downvote
FROM postvotes pv
LEFT JOIN
(
SELECT puv.pid, count(puv.vote) as upvote
FROM postvotes puv
WHERE puv.vote = 1
GROUP BY puv.pid
) uv
ON pv.pid = uv.pid
LEFT JOIN
(
SELECT pdv.pid, count(pdv.vote) as downvote
FROM postvotes pdv
WHERE pdv.vote = -1
GROUP BY pdv.pid
) dv
ON pv.pid = dv.pid
这应该产生以下数据:
+-----+--------+----------+
| pid | upvote | downvote |
+-----+--------+----------+
| 19 | 1 | 2 |
| 18 | 2 | NULL |
| 17 | NULL | 1 |
+-----+--------+----------+
现在剩下的就是加入post和user表来获取你所追求的其他数据,并在where子句中添加其他条件,例如:
SELECT p.id, p.uid, p.post, u.username, uv.upvote, dv.downvote
FROM posts p
JOIN users u ON p.uid = u.id
LEFT JOIN
(
SELECT puv.pid, count(puv.vote) as upvote
FROM postvotes puv
WHERE puv.vote = 1
GROUP BY puv.pid
) uv
ON p.id = uv.pid
LEFT JOIN
(
SELECT pdv.pid, count(pdv.vote) as downvote
FROM postvotes pdv
WHERE pdv.vote = -1
GROUP BY pdv.pid
) dv
ON p.id = dv.pid
WHERE p.deleted = 0
ORDER BY p.created DESC
LIMIT 0,10