为什么这两个查询给出不同的结果?
无论已删除列的值如何,此查询都会提供所有记录。就好像忽略了这个选择一样:
SELECT mcm.record_id, mc.category, mc.category_id, mc.deleted, mcm.member_id
FROM mailing_category mc
LEFT OUTER JOIN mailing_category_membership mcm
ON mc.category_id = mcm.category_id
AND mcm.member_id = 6346
AND mc.deleted = 'false'
WHERE mcm.record_id IS NULL
此查询只选择已删除列为false的记录,这正是我想要的。
SELECT mcm.record_id, mc.category, mc.category_id, mc.deleted, mcm.member_id
FROM mailing_category mc
LEFT OUTER JOIN mailing_category_membership mcm
ON mc.category_id = mcm.category_id
AND mcm.member_id = 6346
WHERE mcm.record_id IS NULL
AND mc.deleted = 'false'
为什么这两个查询给出不同的结果?我使用的是MySQL版本5.5.37。
发布于 2014-07-19 03:28:15
left outer join
的逻辑是从第一个表中获取所有记录。如果第二个表中有一个或多个匹配,则将这些匹配包括在结果集中。如果没有匹配,则仍然将原始记录包含在结果集中,其他所有列都为NULL。匹配意味着on
子句的计算结果为true。
这适用于对第一个表的筛选。所以在这句话中:
FROM mailing_category mc LEFT OUTER JOIN
mailing_category_membership mcm
ON mc.category_id = mcm.category_id AND mcm.member_id = 6346 AND
mc.deleted = 'false'
您认为您正在过滤mc.deleted = 'false'
。但是,这只是意味着没有匹配(因为on
子句的计算结果为false)。记录仍然保存,因为这是left outer join
的逻辑。
当您将mc
上的条件移到where
子句时,过滤将按您的预期进行。
发布于 2014-07-19 03:23:12
因为当执行外部联接时,筛选会在查询处理的不同时间发生。
其中子句是根据外部联接的结果执行的。
ON子句在外部联接的输入上执行。
对于内部连接也是如此;但在这种情况下,不同的处理时间仍然相同。
发布于 2014-07-19 03:28:18
就好像忽略了这个选择一样:
因为您使用的是外部连接。
左外部联接意味着返回第一个表中的所有行,如果第二个表中有符合联接条件的行,则将它们排成一行。然后应用WHERE子句。如果它们不匹配,那么仍然会得到一行,只有第二个表的NULL
值。
换句话说,outer join
从不使用dis--可以使行不被返回。当然,WHERE
子句将与inner join
一样。
您可能会问,如果外部联接没有取消行的资格,那么联接条件对它们有什么影响呢?简单地,他们指定,对于右边的给定行,如果它应该与左边的一行对齐的话。
所以你认为过滤器没有被应用。实际上,它应用于从第二个表中选择行以与第一个表一起使用。
https://stackoverflow.com/questions/24836393
复制相似问题