2008-12-16 82 views
10

这是Mysql的表连接中的“using”和“on”有什么区别?

... 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子句中如何进行交互?

+0

只是出于兴趣你使用的数据库是什么?我只是尝试了SQL Server上的USING语法,它似乎不起作用。 – 2008-12-16 16:13:36

+0

我正在使用MySQL – Pyrolistical 2008-12-16 17:47:05

回答

12

我不使用using语法,因为

  1. 我的大部分的连接并不适合它(不是被匹配的相同的字段名,和/或多个匹配的连接)和
  2. 它不是立即明显它转化为与两个以上的表

即假设有“身份证”和“ID_2”列3代表的情况下,确实

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) 

还是其他什么东西来着?

对于某个特定的数据库版本来说,这是一个相当简单的练习,但我没有很大的信心认为它在所有数据库中都是一致的,并且我不是唯一一个必须维护我的代码(所以其他人也必须知道它相当于什么)。

与其中Vs上的明显的区别是如果连接是外:

假定T1与单个ID字段,包含值1,并用ID和值字段一个T2一行(一个行,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 

没有给出的行中,由于在需要进行匹配,而

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

您的解释看起来正确。 This article可能会有所帮助。

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

+1

不,根据ON子句中的连接类型条件可能与where子句具有非常不同的含义。 – 2008-12-16 02:24:57

1

我相信你是正确的 - USING(xx)是加入两个具有相同名称的列的简称。

至于第二个问题,两个查询可能是是相同的或可能是不同的,具体取决于特定于数据库的查询计划程序实现。为了找出你自己(至少在postgres中)做一个EXPLAIN SELECT ...来看看如何执行查询计划。

1

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

使用条款的缺点是两个表必须具有相同的列名称。

5

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>任何其他可用于周围的表达只是它们可以被包含需要上下文)。

此外,没有其他表加入查询可能有一个由该名称的列,否则查询是不明确的,你应该得到一个错误。

关于您对附加条件的疑问,假设您使用INNER JOIN,它应从逻辑上给出与查询相同的结果,但优化计划可能会受到影响,具体取决于RDBMS实施。如果在连接中包含条件,则OUTER JOIN也会给出不同的结果,而WHERE子句中包含条件。

0

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

0

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

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

那么结果集将有两列名为common,特别是t1.commont2.common,因为它是不明确的不合格的名字将不会在查询工作。

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

JOIN ... USING (common) 

那么结果集将只有一个名为common一列,而这将是一个不合格的名称 - 既不t1.common也不t2.common将出席会议。

相关问题