MYSQL-使用AND in JOIN VS WHERE子句

MYSQL-使用AND in JOIN VS WHERE子句,mysql,Mysql,如果我有这个问题: select * from tableA left outer join tableB on tableA.id=tableB.id AND tableB.foo = 1 where tableA.owner=10 我得到29个结果,但如果我将其移动到WHERE子句中,如: select * from tableA left outer join tableB on tableA.id=tableB.id where tableA.owner=10 AND tableB.f

如果我有这个问题:

select * from tableA
left outer join tableB on tableA.id=tableB.id
AND tableB.foo = 1
where tableA.owner=10
我得到29个结果,但如果我将其移动到WHERE子句中,如:

select * from tableA
left outer join tableB on tableA.id=tableB.id
where tableA.owner=10
AND tableB.foo = 1
然后我只得到17个结果

我环顾了四周,找不到一个明确的指南,说明在JOIN和WHERE子句中使用and时的区别。谁能给我解释一下吗


此外,如果在联接中执行类似于
和tableB.foo=NULL的操作,则查询结果中所有的tableB.foo字段都为NULL,即使它们在表中不为NULL。在被WHERE子句过滤之前,JOIN子句中的AND是否会更改FROM选择中的该字段?

外部联接到的表的所有条件都应该位于JOIN子句中(与第一个查询类似)。将它放在
WHERE
子句中(就像您的第二个查询)会隐式地将
外部联接转换为
内部联接


至于您关于
和tableB.foo=NULL的问题,这是不正确的MySQL语法。NULL需要,使用诸如
IS NULL
之类的运算符。您应该使用
,而tableB.foo则为NULL

外部联接到的表的所有条件都应该在
JOIN
子句中(就像您的第一个查询一样)。将它放在
WHERE
子句中(就像您的第二个查询)会隐式地将
外部联接转换为
内部联接


至于您关于
和tableB.foo=NULL的问题,这是不正确的MySQL语法。NULL需要,使用诸如
IS NULL
之类的运算符。您应该使用
,而tableB.foo为NULL

外部联接的联接方式与内部联接的联接方式相同。另外,当一条记录没有匹配项时,一条所有列都设置为null的伪记录将被连接(因此您仍然可以从结果中的第一个表中获取行)

在第一个查询中,您正在tableB中查找ID相同且foo=1的匹配项。对于tableA中没有此类匹配的记录,仍然会得到一个结果行(所有tableA字段都为空)

在第二个查询中,您正在tableB中查找具有相同ID的匹配项。对于tableA中没有此类匹配项的记录,您仍然会得到一个结果行(所有tableA字段均为空)。然后在where子句中,只保留foo=1的行。这将取消所有外部连接记录(因为它们的foo为null),并且您将处于使用普通内部连接时的状态


因此,始终将所有条件放在on子句中的外部联接表上。(不过有一个例外:反联接,但您可以在下次学习该模式。)

外部联接的联接方式与内部联接的联接方式相同。另外,当一条记录没有匹配项时,一条所有列都设置为null的伪记录将被连接(因此您仍然可以从结果中的第一个表中获取行)

在第一个查询中,您正在tableB中查找ID相同且foo=1的匹配项。对于tableA中没有此类匹配的记录,仍然会得到一个结果行(所有tableA字段都为空)

在第二个查询中,您正在tableB中查找具有相同ID的匹配项。对于tableA中没有此类匹配项的记录,您仍然会得到一个结果行(所有tableA字段均为空)。然后在where子句中,只保留foo=1的行。这将取消所有外部连接记录(因为它们的foo为null),并且您将处于使用普通内部连接时的状态

因此,始终将所有条件放在on子句中的外部联接表上。(但有一个例外:反连接,但您可以在下次学习该模式。)

您可以在此处看到:您可以在此处看到: