2

我有一张桌子user,此外INNER JOIN还有桌子cities和其他一些桌子。现在我也有下表:

blocked_user
--------------------------------------------------------
id | user1_id | user2_id | timestamp

我该如何使用LEFT JOIN WHERE IS NULL,所以两个用户组合(用户 1 被阻止的用户 2 或用户 2 被阻止的用户 1)都被排除在搜索结果之外?

user
--------------------------------------------------------
id | username | ...

非常感谢您的帮助!

4

2 回答 2

2

在这种情况下,我猜关键字 NOT EXISTS 至少在语义上是合适的。

SELECT * FROM user u
WHERE NOT EXISTS (
    SELECT * FROM blocked_user b 
    WHERE 
        b.user1_id = u.id 
    OR  b.user2_id = u.id
)

确实也可以选择使用:

SELECT * FROM user u LEFT JOIN blocked_user b ON b.user1_id = u.id 
                                              OR b.user2_id = u.id
WHERE b.id IS NULL

但关于表演我不知道哪一个更有效率。

rgds。

于 2012-06-12T13:46:39.473 回答
2

我猜你有一个当前用户(执行请求的用户),你想隐藏他们阻止的所有用户或阻止他们的所有用户。我还假设user1_id是进行阻止的用户,并且user2_id是他们阻止的用户。您应该编辑您的问题以使这些观点更清楚。

如果这是正确的,这就是我会做的:

SELECT id, username

FROM user

LEFT JOIN (
    SELECT DISTINCT user2_id AS blockee_id
    FROM blocked_user
    WHERE user1_id = :current_user_id
) this_user_blocked
ON user.id = this_user_blocked.blockee_id

LEFT JOIN (
    SELECT DISTINCT user1_id AS blocker_id
    FROM blocked_user
    WHERE user2_id = :current_user_id
) blocked_this_user
ON user.id = blocked_this_user.blocker_id

WHERE this_user_blocked.blockee_id IS NULL
AND blocked_this_user.blocker_id IS NULL

我认为使用两个单独的结构是有意义的,LEFT JOIN ... WHERE ... IS NULL因为您实际上是在检查两种不同的情况。

于 2012-06-12T13:50:37.477 回答