LEFT JOIN(OUTER JOIN)与INNER JOIN的条件

问题描述:

SELECT A.COL1, B.COL1,C.COL1 
FROM TABLEA A 
LEFT JOIN TABLEB B ON A.COL1 = B.COL1 
LEFT JOIN TABLEC C ON (
     C.COL3 IS NOT NULL 
     AND (
       C.COL2 = 664 
       AND A.COL1 = C.COL1 
     ) 
) 

关于SQL的技术性,LEFT JOIN TABLE C ON之后括号内的条件是什么意思?为什么这些必要?LEFT JOIN(OUTER JOIN)与INNER JOIN的条件

+0

你的意思是,我们为什么需要加入标准? – dasblinkenlight

+0

不,我的意思是在表c的eft连接中,括号中写入的条件的含义是什么,为什么我们需要写这个?为什么我不能使用简单的where子句?我曾尝试在相同表和连接上使用简单的where子句,但结果不同。 –

+0

这个SQL已经被现在有人写给我了。 –

早期版本的ANSI SQL不包含连接条件的ON子句 - 它对所有内容都使用where子句。这对于内部连接来说很好,但是随着数据库应用程序开始使用外部连接,这种方法出现了一些问题。你们中的一些人可能还记得*==*的原始ANSI-89时代语法。这些用于谓词来定义外部联接的行为。在这种情况下,我们除了从A保留不匹配的行正常行从连接返回:

SELECT A.COL1, B.COL1,C.COL1 
FROM TABLEA A 
LEFT JOIN TABLEB B ON A.COL1 = B.COL1 
LEFT JOIN TABLEC C ON (
     C.COL3 IS NOT NULL 
     AND (
       C.COL2 = 664 
       AND A.COL1 = C.COL1 
     ) 
) 

这是非常有用的,当你试图找出在查询中会发生什么。它有助于语义上定义应从联接中返回的一组行。

ON子句:这个语法允许您为ON子句用于连接表,其中列名不两个表中同时匹配表 在加入主键指定的列名。连接条件将从WHERE子句中的过滤条件中删除。

+0

该报价不清楚和困惑。加盟是在条件下,而不是“两个表中的关键”;任何两个表都可以在任何情况下或没有情况下加入。最后一句话没有意义;但是如果查询编写器或实现从WHERE到ON“移除”条件,那么通常它必须在任何OUTER JOIN之后评估的非OUTER连接的ON。 – philipxy

内部联接(JOIN或INNER JOIN,CROSS JOIN或逗号)首先进行交叉连接。 (Ie返回可以通过从左表追加一行并从右表追加一行的所有行)。然后,任何ON都会删除不符合条件的行。对于左表(LEFT)或右表(右)或两个表(FULL),OUTER JOIN返回相应INNER JOIN 的行,任何不匹配的行使用NULL扩展。 FROM WHERE删除不符合条件的行后。

如果某个条件处于ON状态,则会在FROM中删除匹配的行。但是如果这个条件是在WHERE中,那么匹配行和通过后面的连接合并它们的任何行仍然会被删除。所以如果一个FROM只有内部连接,那么无论是条件是ON还是WHERE都无关紧要。

但是,如果FROM具有条件上的OUTER JOIN,那么删除不满足条件的交叉连接行并添加某些NULL扩展的行,而将该条件移至WHERE则删除而不添加。

该语言没有必要为INNER JOIN开启,因为替代t1 INNER JOIN t2 ON condition可能涉及到(SELECT * FROM t1 INNER JOIN t2 WHERE condition)

从上面可以得出以下结论:对于任何最后一个OUTER JOIN(包括没有OUTER JOIN)的INNER JOIN序列,可以在ON和WHERE之间*移动条件。但不适用于任何最后的OUTER JOIN或之前的ON,因为它们可能会影响其输入,因此会影响输出NULLed行。如果这样的条件从ON移到WHERE,没有理由期待相同的结果。

对于您的代码:可能查询的目的是将A.COL1作为ID与关联的A,B和C信息一起使用,但是那些没有包含B信息的信息仍然包含在内(B & C信息为NULL)和那些做但没有C信息或做,但没有非空C.COL3或做,但没有C.COL2 = 664然而包括(C信息为空)。

+0

感谢您的好回答,会有很好的例子.. –

随着OUTER JOINC可能是NULL因为没有匹配A.COL1.

如果是这样的话,那就永远不会C.COL2 = 664意味着任何WHERE语句会扔掉的行。

通过将条件放入ON子句中,您要求应用于JOIN条件,而不是作为结果的筛选器。

对于非外部联接,它没有区别。