在MySQL版本8系列中,有一个SQL使用了聚合函数,比如count。执行LEFT JOIN时,WHERE子句中指定的“IS NULL”模式的行为与ON子句中指定的“IS NULL”模式的行为不同。为什么?
-- pattern1
SELECT count(a.value)
FROM A AS a
LEFT JOIN B AS b
ON a.id = b.id
WHERE b.value IS NULL
;
-- pattern2
SELECT count(a.value)
FROM A AS a
LEFT JOIN B AS b
ON a.id = b.id
AND b.value IS NULL
;
-- pattern1's result = 3549
-- pattern2's result = 4000
一个表有4000条记录。
4条答案
按热度按时间1aaf6o9v1#
当一个表的条件被放置在WHERE中时,它将在连接后应用。
当一个表的条件设置为ON时,它将在连接期间应用(但这看起来像之前)。
第一个SELECT连接表而不附加条件。
第二个SELECT在WHERE中通过右表包含附加条件。该条件在接合之后应用,即第一个SELECT返回的行集,只返回一行。
第三个SELECT在ON中包含附加条件by right table,该条件应用于源表。这是另外示出的。
第四个SELECT包含WHERE中左表的附加条件。该条件在接合之后应用,即第一个SELECT返回的行集,只返回两行。
第五个SELECT包含ON中左表的附加条件,该条件应用于源表。这是另外示出的。
fiddle
cld4siwp2#
如果将它放在on子句中,则每行至少得到一个结果行,只要b.value为null,就有B个rows联接
在where子句中使用它,您可以跳过任何存在一个或多个B行并且b.值都不为null的a行。
ngynwnxp3#
第一个在连接过程中应用
b.value IS NULL
条件,而第二个将b.value IS NULL
应用于最终结果集。参见dbfiddle。
ryevplcw4#
当使用
WHERE b.value IS NULL
时,输出将只包含任何具有b.value = NULL
的记录。即在B中没有找到匹配的记录,或者匹配的B记录具有value = NULL
。表A中的某些记录可能不会在匹配的结果中结束,并且b.值不为null。而如果使用
AND b.value IS NULL
,这意味着,从B表中,只有那些值为空的记录将被选为RIGHT表输出。但是在A表中,所有的记录都将导致输出-包括那些具有b.值NOT NULL的记录。因此,模式2可以在输出中给予更多结果。