如何解决多联接和求和的问题
如果具有以下三个PostgreSQL表:
发布表:
postid | title | author | created
投票表:
postid | username | vote
其中,如果用户投票赞成该帖子,则投票等于1;如果用户投票反对,则投票等于0;如果用户投票反对该帖子,投票等于-1。
评论表:
commentID | parentID | postID | content | author | created
如果评论不是答复,则parentID为null。
我想现在为每个帖子接收其标题,作者,创建日期,所有投票的总和以及 当前登录用户的投票数和评论数。 我的用户投票已经出现问题,问here,有人帮助我获得以下查询:
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
现在,我尝试了另一个LEFT JOIN
来获取评论数量,例如:
COUNT(DISTINCT comments) FILTER (WHERE comments.parentID IS NULL) as numComments
LEFT JOIN comments on post.postID = comments.postID
但是,尽管评论数起作用,但由于该帖子的投票数是错误的,因为 由于存在其他联接,这些行似乎多次出现,从而产生了错误的总和,因此我在解决该问题的方法上遇到了一些麻烦。
我已经尝试将注释的数量作为子查询来获取,以使其独立于 没有成功的票数。 任何进一步的帮助将不胜感激! :-)
解决方法
分别计算值。 join
个引起笛卡尔积。这是相关子查询或横向联接可以提供帮助的地方:
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;
,
通常,在加入之前,您通常会在子查询中进行预聚合,例如:
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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。