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)
【问题讨论】:
但是Saget
被Bob
屏蔽了
其实结果不应该是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 啥区别?