SQL连接添加具有空值的行

时间:2017-10-04 13:18:41

标签: sql postgresql join

我正在使用PostgreSQL克隆Twitter。用户可以撰写帖子并可以共享。每个用户都有一个时间表,其中显示了他所关注的人员的帖子和份额。我还必须显示原始作者的共享帖子(转发)和常规帖子之间的区别。加入表时我遇到以下问题:

Post                                                            
post_id | user_id | text                                        
1         1         text                                        

Shares                                                          
post_id | user_id                                               
1         2                                                     

Join_result                                                     
Post.post_id | Post.user_id | Post.text | Shares.post_id | Shares.user_id                                                           
1              1              text        1                2    

然后我按Post.user_idShares.user_id进行过滤。但是,有了这个结果,我不知道我是否正在显示帖子,因为它是user 2分享或user 1帖子。对我来说一个很好的解决方案,就是这个连接表:

Join_result                                                     
Post.post_id | Post.user_id | Post.text | Shares.post_id | Shares.user_id                                                           
1              1              text        null             null 
1              1              text        1                2

现在我可以正确过滤:

(Post.user_id in following and Share.user_id is NULL) or Share.user_id in followings

在此示例中,如果用户跟随user 1,则返回第一行;如果他跟随user 2我得到第二个,如果他跟随这两个用户,则返回两行。

我已经使用UNION查询解决了这个问题,但我想知道是否有其他解决方案(并且更好)。

编辑查询:

SELECT p0* f1.*, FROM "posts" AS p0
LEFT OUTER JOIN "forwards" AS f1 ON f1."post_id" = p0."id" 
INNER JOIN (SELECT id FROM users AS u0
            INNER JOIN follows AS f1 ON (f1.follower_id = $1) AND (f1.following_id = u0.id) UNION
            SELECT id FROM users AS u1 WHERE (u1.id = $1)
) AS f3 ON (p0."author_id" = f3."id") OR (f1."user_id" = f3."id") ORDER BY p0."inserted_at" DESC

1 个答案:

答案 0 :(得分:0)

您正在使用LEFT OUTER JOIN,在这种情况下,如果不存在转发,则会在结果中设置空值。

有关更多信息,请参阅此帖子: What is the difference between "INNER JOIN" and "OUTER JOIN"?