mysql:需要返回投票最多的前三名用户两个子查询之和的一列结果java/spring mvc

ut6juiuv  于 2021-06-23  发布在  Mysql
关注(0)|答案(1)|浏览(315)

我有一个springmvc博客,它提供了帖子和评论投票的功能。我想返回前3名用户的基础上,他们已经收到的票数对他们的所有职位和评论。
table:
用户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 
  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

太好了!但我希望第三列的sum结果本质上是“totalvotes”,并且包含这两个子查询的总和。然后我将按u.id按totalvotes 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())时,子查询是分开工作的(它们为我提供了正确的用户),但是如果我运行整个块,我会得到错误“operand should contain 1 column(s)”,所以我删除它们并恢复为只选择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;
hrysbysz

hrysbysz1#

不要将子查询放在“选择”部分中,而是将它们联接到“用户”表中:

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;

小提琴:http://sqlfiddle.com/#!9802年9月11日

相关问题