2012-06-12 30 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。