外部联接内的SQL内部联接;嵌套改变结果

时间:2014-09-17 12:22:57

标签: sql join inner-join outer-join

我有点惊讶这两个查询给出了不同的结果:

第一次查询:

SELECT a.number, a.name , b.*
FROM Atable a
LEFT OUTER JOIN Btable b
JOIN Ctable c ON c.number = b.number
ON b.number = a.number
ORDER BY a.number;

第二次查询:

SELECT a.number, a.name , b.*
FROM Atable a
LEFT OUTER JOIN Btable b ON b.number = a.number
JOIN Ctable c ON c.number = b.number
ORDER BY a.number

我的期望是这两个都会返回第一个查询所做的结果。第一个查询返回TableA中的每一行;但是,出乎意料的是,第二行只返回TableA的结果,如果它们也存在于TableC中。

为什么从C到B的连接在第二个查询中限制TableA而在第一个查询中不限制?

谢谢!

1 个答案:

答案 0 :(得分:3)

你的第一个查询,用parens来澄清它是如何被解析的:

SELECT a.number, a.name , b.*
FROM Atable a LEFT OUTER JOIN
     (Btable b JOIN
      Ctable c
      ON c.number = b.number
     ) ON b.number = a.number
ORDER BY a.number;

连续两个on子句令人困惑,因此括号有帮助。这清楚地表明您保留了第一个表中的所有行。

第二个查询是:

SELECT a.number, a.name , b.*
FROM (Atable a LEFT OUTER JOIN
      Btable b
      ON b.number = a.number
     ) JOIN
     Ctable c
     ON c.number = b.number
ORDER BY a.number;

您正在加入第一次加入的结果。因此,只有匹配的行才会转到结果集。

当您进行多个连接时,我建议对所有连接使用left join。混合内部和外部连接可能会导致混淆。