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

Pyr*_*cal 13 mysql sql join

这是

... T1 join T2 using(ID) where T2.VALUE=42 ...
Run Code Online (Sandbox Code Playgroud)

同样的

... T1 join T2 on(T1.ID=T2.ID) where T2.VALUE=42 ...
Run Code Online (Sandbox Code Playgroud)

对于所有类型的连接?

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


现在换另一个问题:

以上是一样的

... T1 join T2 on(T1.ID=T2.ID and T2.VALUE=42) ...
Run Code Online (Sandbox Code Playgroud)

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

Ceb*_*yre 15

我不使用USING语法,因为

  1. 我的大多数联接都不适合它(不是匹配的字段名,和/或连接中的多个匹配)和
  2. 在具有两个以上表的情况下,它并不是立即明显的

即假设3个表具有'id'和'id_2'列,确实如此

T1 JOIN T2 USING(id) JOIN T3 USING(id_2)
Run Code Online (Sandbox Code Playgroud)

成为

T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T1.id_2=T3.id_2 AND T2.id_2=T3.id_2)
Run Code Online (Sandbox Code Playgroud)

要么

T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T2.id_2=T3.id_2)
Run Code Online (Sandbox Code Playgroud)

还是别的什么?

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

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
Run Code Online (Sandbox Code Playgroud)

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

SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID AND T2.VALUE=42)
Run Code Online (Sandbox Code Playgroud)

将给出一行值

1, NULL, NULL
Run Code Online (Sandbox Code Playgroud)

因为ON只需要匹配连接,由于外部连接是可选的.


Bil*_*win 11

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

A JOIN B USING (column1)

A JOIN B ON A.column1=B.column1
Run Code Online (Sandbox Code Playgroud)

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

A JOIN B USING (column1, column2)

A JOIN B ON A.column1=B.column1 AND A.column2=B.column2
Run Code Online (Sandbox Code Playgroud)

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

此外,查询中没有其他表连接可能有一个该名称的列,否则查询是不明确的,你应该得到一个错误.

关于附加条件的问题,假设您使用INNER JOIN它,它应该在逻辑上从查询中提供相同的结果,但优化计划可能会受到影响,具体取决于RDBMS实现.也OUTER JOIN给出了不同的结果,如果你包括在与加盟的条件WHERE子句.


Mar*_*eed 7

我在其他答案中没有看到结果中存在差异。如果你这样做:

 JOIN ... ON t1.common = t2.common
Run Code Online (Sandbox Code Playgroud)

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

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

 JOIN ... USING (common)
Run Code Online (Sandbox Code Playgroud)

那么结果集将只有一个名为 的列common,并且它将是一个非限定名称 - 既不存在t1.common也不t2.common存在。