首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL JOIN ON vs USING?

MySQL JOIN ON vs USING?
EN

Stack Overflow用户
提问于 2012-07-07 00:16:50
回答 5查看 213.2K关注 0票数 299

在MySQL JOIN中,ONUSING()有什么区别?据我所知,USING()只是更方便的语法,而ON在列名不相同时允许更多的灵活性。然而,这种差异是如此之小,你可能会认为他们只是废除了USING()

这有没有比表面看起来更多的东西?如果是,在给定的情况下我应该使用哪一个?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-07-07 01:32:52

这主要是语法上的糖,但有几个区别值得注意:

上的是两者中更通用的一个。可以根据一列、一组列甚至一个条件来连接表。例如:

代码语言:javascript
复制
SELECT * FROM world.City JOIN world.Country ON (City.CountryCode = Country.Code) WHERE ...

当两个表共享一个名称完全相同的列时,使用非常有用。在这种情况下,可以说:

代码语言:javascript
复制
SELECT ... FROM film JOIN film_actor USING (film_id) WHERE ...

另外一个很好的待遇是,不需要完全限定连接的列:

代码语言:javascript
复制
SELECT film.title, film_id -- film_id is not prefixed
FROM film
JOIN film_actor USING (film_id)
WHERE ...

为了说明,要在上使用执行上述操作,我们必须这样写:

代码语言:javascript
复制
SELECT film.title, film.film_id -- film.film_id is required here
FROM film
JOIN film_actor ON (film.film_id = film_actor.film_id)
WHERE ...

请注意SELECT子句中的film.film_id限定。只说film_id是无效的,因为这会造成歧义:

错误1052 (23000):字段列表中的列'film_id‘不明确

对于select *,,使用ON时,连接列在结果集中出现两次,而使用USING时,连接列只出现一次

代码语言:javascript
复制
mysql> create table t(i int);insert t select 1;create table t2 select*from t;
Query OK, 0 rows affected (0.11 sec)

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.19 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select*from t join t2 on t.i=t2.i;
+------+------+
| i    | i    |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> select*from t join t2 using(i);
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

mysql>
票数 476
EN

Stack Overflow用户

发布于 2014-09-12 19:16:00

当我发现ONUSING更有用的时候,我想我会在这里插话。这是在查询中引入OUTER连接的时候。

ON的好处在于,在维护OUTER连接的同时,允许限制查询所连接的表的结果集。试图通过指定WHERE子句来限制结果集将有效地将OUTER联接更改为INNER联接。

诚然,这可能是一个相对的角落案例。但值得一试……

例如:

代码语言:javascript
复制
CREATE TABLE country (
   countryId int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
   country varchar(50) not null,
  UNIQUE KEY countryUIdx1 (country)
) ENGINE=InnoDB;

insert into country(country) values ("France");
insert into country(country) values ("China");
insert into country(country) values ("USA");
insert into country(country) values ("Italy");
insert into country(country) values ("UK");
insert into country(country) values ("Monaco");


CREATE TABLE city (
  cityId int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
  countryId int(10) unsigned not null,
  city varchar(50) not null,
  hasAirport boolean not null default true,
  UNIQUE KEY cityUIdx1 (countryId,city),
  CONSTRAINT city_country_fk1 FOREIGN KEY (countryId) REFERENCES country (countryId)
) ENGINE=InnoDB;


insert into city (countryId,city,hasAirport) values (1,"Paris",true);
insert into city (countryId,city,hasAirport) values (2,"Bejing",true);
insert into city (countryId,city,hasAirport) values (3,"New York",true);
insert into city (countryId,city,hasAirport) values (4,"Napoli",true);
insert into city (countryId,city,hasAirport) values (5,"Manchester",true);
insert into city (countryId,city,hasAirport) values (5,"Birmingham",false);
insert into city (countryId,city,hasAirport) values (3,"Cincinatti",false);
insert into city (countryId,city,hasAirport) values (6,"Monaco",false);

-- Gah. Left outer join is now effectively an inner join 
-- because of the where predicate
select *
from country left join city using (countryId)
where hasAirport
; 

-- Hooray! I can see Monaco again thanks to 
-- moving my predicate into the ON
select *
from country co left join city ci on (co.countryId=ci.countryId and ci.hasAirport)
; 
票数 20
EN

Stack Overflow用户

发布于 2015-07-21 08:25:13

Wikipedia包含以下有关USING的信息

USING结构不仅仅是语法糖,因为结果集与带有显式谓词的版本的结果集不同。具体地说,USING列表中提到的任何列都将只出现一次,且具有不合格的名称,而不是为联接中的每个表出现一次。在上面的例子中,只有一个DepartmentID列,没有employee.DepartmentID或department.DepartmentID。

它所讨论的表:

Postgres文档也对它们进行了很好的定义:

ON子句是最常见的连接条件:它接受与WHERE子句中使用的布尔值表达式相同的布尔值表达式。如果ON表达式的计算结果为true,则T1和T2中的一对行匹配。

USING子句是一种速记形式,它允许您利用连接的两端对连接列使用相同名称的特定情况。它接受一个以逗号分隔的共享列名列表,并形成一个连接条件,其中包括每个列名的相等比较。例如,使用(a,b)连接T1和T2会在T1.a = T2.a和T1.b = T2.b上产生连接条件。

此外,JOIN USING的输出取消了冗余列:不需要打印两个匹配的列,因为它们必须具有相等的值。JOIN ON会生成T1中的所有列,然后是T2中的所有列,JOIN USING将为列出的每个列对(按列出的顺序)生成一个输出列,然后是T1中的任何剩余列,最后是T2中的任何剩余列。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11366006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档