2013-03-20 54 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