简体   繁体   English

多个连接和求和的问题

[英]Problems with multiple joins and a sum

If have the following three PostgreSQL tables:如果有以下三个 PostgreSQL 表:

Post table:邮寄表:

postid | title | author | created

Vote table:投票表:

postid | username | vote

where vote is equal to 1 if the user voted the post up, 0 if the user did not vote and -1 if the user voted the post down.如果用户对帖子投了赞成票,则投票等于 1,如果用户没有投票,则为 0,如果用户对帖子投反对票,则为 -1。

Comment table:评论表:

commentID | parentID | postID | content | author | created

where the parentID is null if the comment is not a reply.如果评论不是回复,则 parentID 为 null。

I want to receive now for every post its title, author, created date, sum of all votes and the vote of the current logged in user and the number of comments.我想现在收到每篇文章的标题、作者、创建日期、所有投票的总和以及当前登录用户的投票和评论数量。 I already had problems with the vote of the user and asked here and someone helped me to get the following query:我已经遇到了用户投票的问题,并在这里询问,有人帮我得到了以下查询:

SELECT post.postID as postID, post.title as title, post.author as author,
       post.created as created,
       COALESCE(sum(votes.vote), 0) as voteCount,
       COALESCE(sum(votes.vote) FILTER (WHERE votes.username = :username), 0) as userVote
       FROM post 
       LEFT JOIN votes ON post.postID = votes.postID 
       GROUP BY post.postID 
       ORDER BY voteCount DESC

Now I tried another LEFT JOIN to fetch the number of comments like this:现在我尝试了另一个LEFT JOIN来获取这样的评论数量:

COUNT(DISTINCT comments) FILTER (WHERE comments.parentID IS NULL) as numComments
LEFT JOIN comments on post.postID = comments.postID

However, while the number of comments work, the number of votes on each post is wrong since due to the other join the rows seem to appear multiple times yielding a wrong sum and I have some trouble figuring out a way to solve this.然而,虽然评论数量有效,但每个帖子的投票数量是错误的,因为由于另一个加入,这些行似乎多次出现,产生错误的总和,我在想办法解决这个问题时遇到了一些麻烦。

I already tried to fetch the number of comments as a subquery so that it is independent from the number of votes without success.我已经尝试将评论数量作为子查询获取,以便它与投票数量无关,但没有成功。 Any further help would be very appreciated!任何进一步的帮助将不胜感激! :-) :-)

Count the values separately.分别计算这些值。 The join s are causing a Cartesian product. join导致笛卡尔积。 This is a place where correlated subqueries or lateral joins help:这是相关子查询或横向连接有帮助的地方:

SELECT p.*, v.*, c.*
FROM post p CROSS JOIN LATERAL
     (SELECT SUM(v.vote) as voteCount,
             SUM(v.vote) FILTER (WHERE v.username = :username), 0) as userVote
      FROM votes v
      WHERE p.postID = v.postID 
     ) v CROSS JOIN LATERAL
     (SELECT SUM(c.vote) as commentCount,
             SUM(c.vote) FILTER (WHERE c.username = :username), 0) as userVote
      FROM comments c
      WHERE p.postID = c.postID 
     ) c
ORDER BY voteCount DESC;

You would typically pre-aggregate in subqueries before joining, like so:您通常会在加入之前预先聚合子查询,如下所示:

SELECT p.*
    COALESCE(v.voteCount, 0) as voteCount,
    COALESCE(v.userVote, 0) as userVote,
    COALESCE(c.numComments, 0) as numComments
FROM post p
LEFT JOIN (
    SELECT postID, 
        SUM(vote) as voteCount, 
        SUM(vote) FILTER (WHERE username = :username) userVote
    FROM votes 
    GROUP BY postID
) v ON v.postID = p.postID 
LEFT JOIN (
    SELECT postID, count(*) numComments
    FROM comments
    WHERE parentID IS NULL
    GROUP BY postID
) c ON c.postID = p.postID
ORDER BY voteCount DESC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM