MySQL中表连接中“using”和“on”之间的区别是什么?

时间:2008-12-16 01:39:34

标签: mysql sql join

这是

... T1 join T2 using(ID) where T2.VALUE=42 ...

相同
... T1 join T2 on(T1.ID=T2.ID) where T2.VALUE=42 ...

适用于所有类型的连接?

我对using(ID)的理解是它只是on(T1.ID=T2.ID)的简写。这是真的吗?


现在提出另一个问题:

以上是否与

相同
... T1 join T2 on(T1.ID=T2.ID and T2.VALUE=42) ...

我不认为这是真的,但为什么呢?如果on子句中的条件与where子句中的条件相互作用,那么它是如何交互的?

7 个答案:

答案 0 :(得分:14)

我不使用USING语法,因为

  1. 我的大部分联接都不适合它(不是匹配的字段名,和/或联接中的多个匹配项)和
  2. 在具有两个以上表格的情况下,它并不是立即显而易见的。
  3. 即假设3个表具有'id'和'id_2'列,

    T1 JOIN T2 USING(id) JOIN T3 USING(id_2)
    

    成为

    T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T1.id_2=T3.id_2 AND T2.id_2=T3.id_2)
    

    T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T2.id_2=T3.id_2)
    

    还是别的什么?

    为特定的数据库版本找到这个是一个相当简单的练习,但我并不十分相信它在所有数据库中都是一致的,而且我不是唯一需要维护我的代码的人(所以其他人也必须知道它相当于什么。)

    WHERE与ON的明显区别在于连接是否为外:

    假设T1具有单个ID字段,一行包含值1,T2具有ID和VALUE字段(一行,ID = 1,VALUE = 6),那么我们得到:

    SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID) WHERE T2.VALUE=42
    

    不提供任何行,因为WHERE需要匹配,而

    SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID AND T2.VALUE=42)
    

    将为一行提供值

    1, NULL, NULL
    

    因为ON仅需要匹配连接,由于外部连接,这是可选的。

答案 1 :(得分:10)

USING子句是列的等连接的简写,假设两个表中的列都存在相同的名称:

A JOIN B USING (column1)

A JOIN B ON A.column1=B.column1

您还可以命名多个列,这使得复合键上的连接非常简单。以下连接应该是等效的:

A JOIN B USING (column1, column2)

A JOIN B ON A.column1=B.column1 AND A.column2=B.column2

请注意,USING (<columnlist>)需要括号,而ON <expr>不需要括号(尽管可以在<expr>周围使用parens,只是它们可能包含在任何表达式中其他背景)。

此外,查询中未加入的其他表可能没有该名称的列,否则查询不明确,您应该收到错误。

关于有关其他条件的问题,假设您使用INNER JOIN,它应该在逻辑上从查询中提供相同的结果,但优化计划可能会受到影响,具体取决于RDBMS实现。如果在连接中包含条件而不是OUTER JOIN子句,WHERE也会给出不同的结果。

答案 2 :(得分:1)

你的解释似乎是正确的。 This article可能有帮助。

关于第二个问题,我不明白为什么你的第三个例子的结果应该与前两个例子的结果不同。 “ON”子句中的任何条件都与“WHERE”子句中的条件具有相同的含义。

答案 3 :(得分:1)

我相信你是对的 - 使用(xx)是连接两个名称相同的列的简写。

至于第二个问题,两个查询可能相同或可能不同,具体取决于特定于数据库的查询计划程序实现。要自己查找(至少在postgres中),请执行EXPLAIN SELECT ...以查看查询计划的执行方式。

答案 4 :(得分:1)

如果只有一个连接,则没有区别。

对using子句的下行是两个表必须具有相同的列名。

答案 5 :(得分:1)

我在其他答案中没有提到的结果有所不同。如果你这样做:

 JOIN ... ON t1.common = t2.common

然后结果集将有两列名为common,特别是t1.commont2.common,并且尝试引用非限定名称common将导致查询被拒绝不明确的(尽管两列必然包含相同的值)。

另一方面,如果你这样做:

 JOIN ... USING (common)

然后结果集只有一个名为common的列,它将是一个不合格的名称 - t1.commont2.common都不会出现。

答案 6 :(得分:0)

你在这里得到了答案,我不需要添加它。一旦我对此进行了性能测试,并且始终如一地使用并且总是比ON快。是的我说的是10到20毫秒:) MySQL我在谈论

相关问题