Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:需要返回投票最多的前三名用户。两个子查询之和的结果需要在一列中。Java/springmvc_Mysql_Sql_Top N - Fatal编程技术网

MySQL:需要返回投票最多的前三名用户。两个子查询之和的结果需要在一列中。Java/springmvc

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

我有一个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 
  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的控制台给了我一些错误,但我对其进行了调整并更新了帖子。