我创建了一个小型社交网站,其中包含用户生成的内容。如果用户不喜欢自己发布的内容,他们应该可以选择互相阻止。
所以我使用的是postgresql,我有三个简单的表。
Table User
id (pk) | user_name
1 | a
2 | b
3 | c
Table Post
id (pk) | user_id (fk)
1 | 1
2 | 3
3 | 2
4 | 2
Table Block
id (pk) | blocker_id (fk) | blocked_id (fk)
1 | 1 | 2
2 | 2 | 1
顺便说一句,如您所见,我使用双向阻止,因为我不希望如果user1阻止user2,则user2也不会看到user1的帖子。
我写了一条sql:
SELECT * FROM Post p INNER JOIN Block b
ON p.user_id = b.blocker_id
WHERE b.blocked_id <> @current_user_id
但是,如果用户没有阻止任何人该怎么办?该sql不涉及这种情况,它仅显示在 block 表中具有记录的用户帖子。
我该怎么做?
谢谢。
答案 0 :(得分:2)
您想显示所有帖子,例如当前用户阻止的某个用户发布的帖子。使用NOT EXISTS
或NOT IN
查找被阻止的用户:
SELECT *
FROM post
WHERE user_id not in (select blocked_id from block where blocker_id = @current_user_id);
答案 1 :(得分:2)
首先,我认为您使对称块对称的想法是错误的。想象一下,当user1阻塞user2时,这将在您的情况下在两个方向上创建两个块。如果user1决定取消阻止user2怎么办?在这种情况下,您将需要删除两个记录。但是,如果两个人都想互相阻挡怎么办?在这种情况下,您还将有两个记录。因此,畅通变得矛盾。我的建议是在user1阻止user2时创建一条记录,并同时搜索blocker_id和blocked_id,以便检查谁看不到谁的帖子如下:
select *
from User
join Block
on User.id = Block.blocker_id or User.id = Block.blocked_id
现在,让我们看看您的查询。您不需要加入Block,而是需要检查是否存在Block记录:
select *
from Post p
where p.user_id = @current_user_id and
not exists (select id
from Block
where Block.blocker_id = p.user_id or Block.blocked_id = p.user_id)
请注意,我在PostgreSQL上工作不多(通常在SQL上工作很多),因此,如果我遇到一些语法错误,则可以将其归因于我在PostgreSQL中的无礼。
编辑
解决方案是以下代码:
select *
from Post p
where
not exists (select id
from Block
where ((Block.blocked_id = p.user_id) and (Block.blocker_id = @current_user_id)) or ((Block.blocked_id = @current_user_id) and (Block.blocker_id = p.user_id))
说明:我们需要找到当前用户阻止作者或作者阻止当前用户的阻止记录。