2013-03-20 114 views
15

我有2個簡單的mysql表。第1名爲郵件和有兩行:MYSQL - 只有在LEFT JOIN中沒有行時才選擇

sender | receiver 
Marley | Bob 
Saget | Bob 

第二個叫塊和具有1行:

blocker | blocked 
    Bob | Marley 

我想選擇誰送鮑勃電子郵件的第一個表發送器(S)但不會在阻止表中被阻止。所以結果應該是:

sender 
saget 

我嘗試下面的查詢,但它沒有返回結果:

SELECT * FROM mail 
LEFT JOIN block ON (block.blocker = 'Bob') 
WHERE (block.blocked <> mail.sender) 
+1

但' 「Saget」被「Bob」阻止 – Lamak 2013-03-20 19:15:48

+0

其實結果不應該是'saget',因爲你看到Bob已經阻止了他們。 – 2013-03-20 19:16:07

+0

對不起,我犯了一個愚蠢的錯誤... marley只是被阻止,而saget不是 – 2013-03-20 19:18:19

回答

18

的左連接會產生null行的不匹配。
這就是你需要過濾的那些行null

SELECT * FROM mail 
LEFT JOIN block ON (block.blocker = 'Bob') 
WHERE block.blocker IS NULL 

它是一種扼殺要然而在一個固定值的加盟,更常見的連接(給你的表)將是:

SELECT * FROM mail 
LEFT JOIN block ON (block.blocker = mail.receiver 
       and block.blocked = mail.sender)<<-- these should match 
WHERE block.blocker IS NULL      <<-- select only mismatches 
AND mail.receiver like 'bob'; 
+0

你加入了''Bob''的硬編碼值,沒有別的?這似乎並不正確 – Lamak 2013-03-20 19:18:22

+0

簡易Lamak沒有做的答案... :-)仍然沒有完成....完成。 – Johan 2013-03-20 19:18:58

+0

那麼,現在你完成了?我認爲這仍然缺少一個條件,你還應該檢查發件人是否被阻止 – Lamak 2013-03-20 19:22:50

9

試試這個:

SELECT sender 
FROM mail m 
WHERE NOT EXISTS (SELECT 1 FROM block 
        WHERE blocker = m.receiver 
        AND blocked = m.sender) 
+0

可能應該添加AND接收器='鮑勃',因爲他指定他想要尋找Bob的消息。 – JNK 2013-03-20 19:34:27

+0

@JNK是的,我想過這個要求,但是猶豫加了這個條件,因爲'block'表(顯然)應該是所有的攔截器,不僅僅是'Bob' – Lamak 2013-03-20 19:38:18

+0

謝謝Lamak :)我現在正在嘗試一個不同的查詢導致另一個問題與一個非常類似的情況,所以會發布在一個新的問題 – 2013-03-20 19:49:46