MySQL:需要返回投票最多的前三名用户。两个子查询之和的结果需要在一列中。Java/springmvc
我有一个SpringMVC博客,它具有发布和评论投票的功能。我想根据他们在所有帖子和评论中获得的投票数返回前三名用户 表格: 用户u[id,用户名] 职位p[id,u.id] 注释c[id、p.id、u.id] 后投票pv[p.id,u.id,类型(1或-1)] 意见表决cv[c.id,u.id,类型(1或-1)] 下面的语句通过查询两个单独的投票表,然后将总数相加,为我提供了每个用户的总投票数:MySQL:需要返回投票最多的前三名用户。两个子查询之和的结果需要在一列中。Java/springmvc,mysql,sql,top-n,Mysql,Sql,Top N,我有一个SpringMVC博客,它具有发布和评论投票的功能。我想根据他们在所有帖子和评论中获得的投票数返回前三名用户 表格: 用户u[id,用户名] 职位p[id,u.id] 注释c[id、p.id、u.id] 后投票pv[p.id,u.id,类型(1或-1)] 意见表决cv[c.id,u.id,类型(1或-1)] 下面的语句通过查询两个单独的投票表,然后将总数相加,为我提供了每个用户的总投票数: SELECT (SELECT SUM(type) FROM posts_votes pv
SELECT
(SELECT SUM(type)
FROM posts_votes pv
JOIN posts p ON p.id = pv.post_id
JOIN users u ON u.id = p.user_id
WHERE u.id LIKE ?1)
+
(SELECT SUM(type)
FROM comments_votes cv
JOIN comments c ON c.id = cv.comment_id
JOIN users u ON u.id = c.user_id
WHERE u.id LIKE ?1)
对于每个用户id的WHERE子句,这很好。。。但现在我正试图找到投票率最高的前三名用户,我遇到了太多的困难。这就是我到目前为止所做的:
SELECT u.id, u.username, IFNULL(SUM(pv.type), 0) AS totalPostVotes
FROM posts_votes pv
JOIN posts p ON p.id = pv.post_id
JOIN users u ON u.id = p.user_id
GROUP BY u.id ORDER BY totalPostVotes DESC LIMIT 3
上面的语句本身就是有效的,它按降序给出了:u.id、u.username和totalPostVote。下面的评论也是如此:
SELECT u.id, u.username, IFNULL(SUM(cv.type), 0) AS totalCommentVotes
FROM comment_votes cv
JOIN comments c ON c.id = cv.comment_id
JOIN users u ON u.id = c.user_id
GROUP BY u.id ORDER BY totalCommentVotes DESC LIMIT 3
太好了!但我希望第三列总和结果本质上是“totalVotes”,并包含这两个子查询的总和。然后我将按u.id按TotalVoces DESC LIMIT 3进行分组
大概是这样的:
SELECT u.id, u.username, SUM(
(SELECT IFNULL(SUM(pv.type), 0) AS totalPostVotes
FROM posts_votes pv
JOIN posts p ON p.id = pv.post_id
JOIN users u ON u.id = p.user_id
GROUP BY u.id ORDER BY totalPostVotes DESC LIMIT 1)
+
(SELECT IFNULL(SUM(cv.type), 0) AS totalCommentVotes
FROM comments_votes cv
JOIN comments c ON c.id = cv.comment_id
JOIN users u ON u.id = c.user_id
GROUP BY u.id ORDER BY totalCommentVotes DESC LIMIT 1))
AS totalVotes from users u
GROUP BY u.id, u.username ORDER BY totalVotes DESC LIMIT 3
id | username | totalVotes
2 user2 11
1 user1 11
29 user29 11
所发生的事情是totalVotes的结果确实是“顶级”用户的正确投票计数11,但这些用户中没有一个是真正的顶级用户,并且正确的投票以其他用户的名义重复了3次。我甚至不确定用户在那个时候是如何被分类的,因为他们的顺序不是我能识别的
当我添加SELECT“u.id,u.username”IFNULL(SUM())时,子查询分别工作(它们为我提供了正确的用户),但如果我运行整个块,我会得到错误“操作数应包含1列”,因此我删除它们并恢复为仅选择IFNULL(SUM())
我还注意到子查询只允许限制为1。那我怎么才能拿到前三名呢?我应该在某处进行联合还是“+”就足够了?这相当令人困惑。有人能帮我吗?感谢您的帮助。提前谢谢
更新代码,谢谢你,彼得:
SELECT
u.username,
pv_sum.total AS postTotal,
cv_sum.total AS commentTotal,
IFNULL(pv_sum.total, 0) + IFNULL(cv_sum.total, 0) as totalVotes
FROM users u
LEFT JOIN (
SELECT p.user_id, IFNULL(SUM(pv.type), 0) AS total
FROM posts p
JOIN posts_votes pv ON pv.post_id = p.id
GROUP BY p.user_id
) pv_sum ON pv_sum.user_id = u.id
LEFT JOIN (
SELECT c.user_id, IFNULL(SUM(cv.type), 0) AS total
FROM comments c
JOIN comments_votes cv ON cv.comment_id = c.id
GROUP BY c.user_id
) cv_sum ON cv_sum.user_id = u.id
GROUP BY u.username, postTotal, commentTotal
ORDER BY totalVotes DESC LIMIT 3;
不要将子查询放在选择部件中,而是将它们连接到用户表中:
SELECT
u.username,
pv_sum.total AS postTotal,
cv_sum.total as commentTotal,
IFNULL(pv_sum.total, 0) + IFNULL(cv_sum.total, 0) as totalVotes
FROM users u
LEFT JOIN (
SELECT p.user_id, IFNULL(SUM(pv.type), 0) AS total
FROM posts p
JOIN post_votes pv ON pv.post_id = p.id
GROUP BY p.user_id
) pv_sum ON pv_sum.user_id = u.id
LEFT JOIN (
SELECT c.user_id, IFNULL(SUM(cv.type), 0) AS total
FROM comments c
JOIN comment_votes cv ON cv.comment_id = c.id
GROUP BY c.user_id
) cv_sum ON cv_sum.user_id = u.id
GROUP BY u.id
ORDER BY totalVotes DESC
LIMIT 3;
Fiddle:如果只有一张投票表,而不是两张单独的投票表,那就容易多了。这样,您基本上必须将两个表合并到一个派生表中,获得每个用户的总投票数,并从中获得前3名。你不能用相关的子查询来做这件事。啊,我明白了,该死的。我会考虑修改表格,谢谢你的快速回复!这成功了!非常感谢你,彼得!Intellij的控制台给了我一些错误,但我对其进行了调整并更新了帖子。