2012-06-12 32 views
2

我有一个表user另外INNER JOIN它与表cities和其他一些已经。现在我也有如下表:MySQL:如何左加入WHERE是NULL(user1阻止user2 OR颠倒)?

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

如何使用LEFT JOIN WHERE IS NULL,所以无论用户组合(USER1阻止用户2或用户2堵塞USER1)从搜索结果中排除?

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

非常感谢您的帮助!

+2

'user1_id'和'user2_id'代表什么?你应该考虑重命名这些字段。 – jnylen

回答

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结构,因为你真的检查两种不同的情况。

+0

嗨jnylen!非常感谢您的帮助。不幸的是,我得到一个错误'#1054 - '组声明'中的未知列'2'? – Chris

+0

已更新,修复了有关单独连接的错误和评论。 – jnylen

+0

哇,非常感谢你jnylen!它像魅力一样工作......尽管在两张桌子上都有数百万行,但速度很快!再次感谢! – Chris

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。