2

我试图了解 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

输出不正确

这是为什么 ?

4

4 回答 4

1

发生这种情况是因为在第一种情况下,该where子句在联接之后应用,并将删除仅包含在“外部”联接中的所有行。这些行被删除是因为表中的emailu2对于这些行将是空的,并且任何与null产生 undefined 的比较都意味着该where子句将丢弃这些行。

where外部联接表上的条件实质上将您的外部联接转换回内部联接。

于 2013-10-10T20:08:45.423 回答
0

因为这是 a ,所以如果该子句不成立LEFT JOIN,您将获得一个带有 fromu1和 NULL值的行。但是,该子句适用于整个结果集,因此如果结果为 NULL,则不会返回。u2ONWHEREu2.id

更改LEFT JOININNER JOIN将解决您的问题。

于 2013-10-10T20:10:56.303 回答
0

进行左连接和从右表中选择没有意义。如果您使用左连接并在 JOIN 子句中应用所有条件,您可能会看到意外的结果。WHERE 是在 JOIN 结果之后应用的过滤器,因此除非您的 JOIN 是 INNER,否则 JOIN 和 Where 之间的连接切换条件是不一样的。JOIN 会给出更多的结果。但是如果 JOIN 是 INNER JOIN 那么无论你的条件在哪里,你都会得到相同的结果。

在您的示例中,如果您只是删除 WHERE 您正在选择 ALL Distinct email but from u2. 并且由于您已经离开了非匹配 u2 行的连接 soem,因此不会像使用 WHERE 子句那样进行过滤。

于 2013-10-10T20:14:14.687 回答
0

对于初学者,您的 sqlfiddle 与此页面上的代码不匹配。不过小问题。

简短的回答是这样的:当您添加一个检查左连接条件的 where 子句时,它本质上使它像一个内连接。

于 2013-10-10T20:09:01.173 回答