MYSQL - 仅当 LEFT JOIN 中的行不存在时才选择

Posted

技术标签:

【中文标题】MYSQL - 仅当 LEFT JOIN 中的行不存在时才选择【英文标题】:MYSQL - Select only if row in LEFT JOIN is not present 【发布时间】:2013-03-10 02:01:42 【问题描述】:

我有 2 个简单的 mysql 表。前 1 个叫做 mail,有 2 行:

sender | receiver
Marley | Bob 
Saget  | Bob 

第二个叫做block,有1行:

blocker | blocked
  Bob   | Marley

我想从第一个表中选择发送 Bob 电子邮件但未在阻止表中被阻止的发件人。所以结果应该是:

sender 
 saget

我尝试了以下查询,但没有返回结果:

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

【问题讨论】:

但是SagetBob屏蔽了 其实结果不应该是saget,因为你看,Bob已经屏蔽了他们两个。 对不起,我犯了一个愚蠢的错误...marley 只被阻止,而 saget 没有 【参考方案1】:

左连接将为不匹配生成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';

【讨论】:

您加入的是'Bob'? 的硬编码值,没有别的?这似乎不对 那么,现在你完成了吗?我认为这仍然缺少一个条件,您还应该检查发件人是否被阻止 我认为您的第二个解决方案中的第二行应该是这样的:LEFT JOIN block ON (block.blocker = mail.receiver AND block.blocker = 'Bob')?? 谢谢 Johan :) 我现在正在尝试一个不同的查询,这也导致了一个非常相似的场景的另一个问题,所以将它发布在一个新问题中【参考方案2】:

试试这个:

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

【讨论】:

可能应该添加AND Receiver = 'Bob',因为他指定要查找来自 Bob 的消息。 @JNK 是的,我考虑过这个要求,但犹豫是否要添加那个条件,因为block 表(显然)应该包含所有阻止程序,而不仅仅是Bob 谢谢 Lamak :) 我现在正在尝试一个不同的查询,这也导致了另一个非常相似的场景的问题,所以将它发布在一个新问题中

以上是关于MYSQL - 仅当 LEFT JOIN 中的行不存在时才选择的主要内容,如果未能解决你的问题,请参考以下文章

使用 LEFT OUTER JOIN 检查相关行不存在的最佳方法是啥

MySQL中的LEFT JOIN 和UNIONALL的联合使用

MySQL Left Join Subquery with *

MySQL 数据库中 left outer join 和 left join 啥区别?

mysql left join,right join,inner join的区别

Mysql之inner join,left join,right join详解