我试图理解ON和WHERE如何影响语句的执行,但没有运气..
我有这个声明给了我预期的结果:
SELECT DISTINCT u1.email
FROM user u1
LEFT JOIN user u2
ON u1.email = u2.email
WHERE u1.id != u2.id
交换ON和WHERE给出了相同的结果,但是当我删除WHERE时,我得到更多的结果:
SELECT DISTINCT u1.email
FROM user u1
LEFT JOIN user u2
ON u1.email = u2.email
AND u1.id != u2.id
为什么?
答案 0 :(得分:1)
这是因为在第一种情况下,在连接后应用了<{1}}子句,并将删除仅由“外部”连接包含的所有行。删除这些行是因为where
表中的email
列对于那些行为空,并且与u2
的任何比较都会产生未定义,这意味着null
子句将丢弃这些行
外连接表上的where
条件实际上将您的外连接转回到内连接。
答案 1 :(得分:0)
对于初学者,您的sqlfiddle与此页面上的代码不匹配。虽然是小问题。
简短的回答是这样的:当你添加一个检查左连接标准的where子句时,它基本上使它像一个内连接。
答案 2 :(得分:0)
因为这是LEFT JOIN
,如果u1
子句不成立,您将获得一行u2
的值和ON
的NULL。但是,WHERE
子句适用于整个结果集,因此如果u2.id
变为NULL,则不会返回它。
将LEFT JOIN
更改为INNER JOIN
将解决您的问题。
答案 3 :(得分:0)
执行LEFT连接和从右表中选择没有意义。 如果您使用左连接并在JOIN子句中应用所有条件,您可能会看到意外的结果。在JOIN结果之后应用过滤器,所以除非JOIN是INNER,否则JOIN和Where之间的切换条件不一样。 JOIN会给出更多结果。 但如果JOIN是INNER JOIN,那么无论你的条件在哪里,你都会得到相同的结果。
在您的示例中,如果您只是删除了在哪里选择了所有不同的电子邮件,但是来自u2。并且当你离开时,不匹配的u2行的连接soem将不会像WHERE子句那样被过滤。