左加入更多条件/加入

时间:2017-02-01 20:35:12

标签: mysql left-join inner-join

如何处理您想要使用Left Join的情况,因为数据可能存在也可能不存在。但是,如果Left Join确实找到了一些数据,您是否希望通过在另一个表上加入左连接数据来进一步限制左连接数据? (不从结果中删除原始数据)。

我认为可能需要更多JoinWhere或子查询。

这是我尝试的内容:

SELECT users.*, failed_logins.*
FROM users
LEFT JOIN failed_logins ON failed_logins.user_id = users.user_id
INNER JOIN banned ON banned.ip_address = failed_logins.ip_address

但如果banned中没有匹配failed_logins的数据,则会导致无法显示数据。

如果banned中有匹配的行,我们希望包含bannedfailed_logins中的行。否则,应排除failed_loginsbanned的行。但是应该始终包含从users抓取的数据。

1 个答案:

答案 0 :(得分:2)

INNER JOIN中的条件将要求failed_logins.ip_address具有非NULL值。将排除该列具有NULL值的任何行。而这将否定"外在性"联接到failed_logins。 (usersfailed_logins中没有匹配行的任何行,外部联接将从failed_logins发明一个虚拟匹配行,匹配虚拟中的所有列row将为NULL。

因此,我们需要一种方法来返回NULL的{​​{1}}值。

一种选择是使内连接成为外连接。也就是说,将failed_logins.ip_address替换为INNER

还有其他一些方法可以解决此类问题。但这实际上取决于我们想要返回的结果集。示例数据和预期结果将大大有助于澄清规范。

修改

在重新阅读问题之后,我们仍然不清楚我们想要返回什么结果。为什么我们需要查看LEFT表? "过滤数据(如果确实存在)"并没有真正解释说明书。

如果banned中有匹配的行,我们希望从结果集中排除行?或者,我们希望返回banned中不存在匹配行的行。

后续

首先在内联视图中使用bannedfailed_logins之间的联接(或派生表以使用MySQL用语)。然后在banned和派生表之间进行外连接。

举个例子:

users

给出SELECT users.* , fl.* FROM users LEFT JOIN ( SELECT f.user_id , f.ip_address FROM failed_logins f JOIN banned b ON b.ip_address = f.ip_address ) fl ON fl.user_id = users.user_id ORDER BY users.user_id, fl.ip_address 样本数据:

failed_logins

user_id ip_address ---------- ------------ 111 127.0.0.1 111 192.168.0.1 222 127.0.0.1 333 192.168.0.1 444 4.4.4.4 示例数据

banned

并假设 ip_address ---------- 127.0.0.1 包含五行,111到555,查询应返回:

users

如果这不符合规范,请考虑提供一些示例数据(包括应该和不应该返回的行的例子)以及预期的输出。