在MySQL中JOIN
,ON
和之间有什么区别USING()
?据我所知,USING()
只是语法更方便,而ON
当列名不相同时,则允许更多的灵活性。但是,这种差别是如此之小,您可能会认为他们只是取消了USING()
。
除了眼球以外,还有什么呢?如果是,在给定情况下应该使用哪个?
using
除了连接外还有其他用法。请参阅stackoverflow.com/a/13750399/632951
在MySQL中JOIN
,ON
和之间有什么区别USING()
?据我所知,USING()
只是语法更方便,而ON
当列名不相同时,则允许更多的灵活性。但是,这种差别是如此之小,您可能会认为他们只是取消了USING()
。
除了眼球以外,还有什么呢?如果是,在给定情况下应该使用哪个?
using
除了连接外还有其他用法。请参阅stackoverflow.com/a/13750399/632951
Answers:
它主要是语法糖,但是有一些区别值得注意:
ON是两者中更通用的。一个人可以在一个列,一组列甚至一个条件上联接表。例如:
SELECT * FROM world.City JOIN world.Country ON (City.CountryCode = Country.Code) WHERE ...
当两个表共享它们所连接的名称完全相同的列时,USING很有用。在这种情况下,您可能会说:
SELECT ... FROM film JOIN film_actor USING (film_id) WHERE ...
另一种不错的方法是不需要完全限定连接列:
SELECT film.title, film_id -- film_id is not prefixed
FROM film
JOIN film_actor USING (film_id)
WHERE ...
为了说明这一点,使用ON进行上述操作,我们必须编写:
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 ...
注意条款中的film.film_id
限定条件SELECT
。仅仅说是无效的,film_id
因为这会造成歧义:
错误1052(23000):字段列表中的“ film_id”列不明确
至于select *
,连接列在结果集中ON
出现两次,而在以下位置只出现一次USING
:
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>
USING
解释为ON
。
USING(
类别,
field_id )
,该类别在通过复合主键进行连接时非常有用,而且我听说优化器确实USING
在某些情况下用于提高性能
USING
MySQL定义还是标准?
当我发现ON
比有用的时候,我想我会介入的USING
。这是当OUTER
连接被引入查询。
ON
受益于允许OUTER
在保留联接的同时限制查询所联接的表的结果集OUTER
。尝试通过指定WHERE
子句来限制结果集将有效地将联接更改OUTER
为INNER
联接。
当然,这可能是一个相对极端的情况。值得放在那里.....
例如:
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)
;
using
提供的所有优势中,它不能与其他谓词结合使用:无效select*from t join t2 using(i) and on 1
。
where hasAirport ;
- 这是什么意思 ?没有价值可与进行比较。
SELECT * FROM country LEFT JOIN city ON country.countryId=city.countryId AND city.city BETWEEN 'C' AND 'E'
将列出所有国家,但仅列出以C或D开头的城市(如果有)。(加上称为“ E”的城镇)
Wikipedia具有以下信息USING
:
但是,由于结果集不同于带有显式谓词的版本的结果集,因此USING构造不仅仅是语法糖。具体来说,在USING列表中提到的任何列将只使用一次无限定名称出现一次,而不对连接中的每个表出现一次。在上述情况下,将只有一个DepartmentID列,而没有employee.DepartmentID或department.DepartmentID。
它正在谈论的表:
在Postgres的文档还定义了他们很好:
ON子句是最通用的连接条件:它采用与WHERE子句中使用的布尔值表达式相同的类型。如果ON表达式的值为true,则T1和T2中的一对行匹配。
USING子句是一种简写形式,可让您利用特定的情况,即连接的双方对连接列使用相同的名称。它采用逗号分隔的共享列名称列表,并形成一个连接条件,其中包括每个条件的相等性比较。例如,使用USING(a,b)联接T1和T2会产生联接条件ON T1.a = T2.a AND T1.b =T2.b。
此外,JOIN USING的输出抑制了多余的列:无需打印两个匹配的列,因为它们必须具有相等的值。JOIN ON产生T1的所有列,然后产生T2的所有列,而JOIN USING产生每个列出的列对的一个输出列(按列出的顺序),接着是T1的所有剩余列,接着是T2的所有剩余列。
对于那些在phpMyAdmin中尝试此操作的人,只需说一句话:
phpMyAdmin似乎有一些问题USING
。作为记录,这是在Linux Mint上运行的phpMyAdmin,版本:“ 4.5.4.1deb2ubuntu2”,数据库服务器:“ 10.2.14-MariaDB-10.2.14 + maria〜xenial-mariadb.org二进制分发版”。
我在phpMyAdmin和Terminal(命令行)中都SELECT
使用JOIN
和USING
来运行命令,而phpMyAdmin中的命令会产生一些令人困惑的响应:
1)最后一个LIMIT
子句似乎被忽略。
2)有时在页面顶部报告的行数与结果有时是错误的:例如,返回4,但在顶部显示“显示0至24行(共2503行,查询花费0.0018秒。)。 ”
正常登录到mysql并运行相同的查询不会产生这些错误。当使用phpMyAdmin运行相同的查询时,也不会发生这些错误JOIN ... ON ...
。大概是phpMyAdmin错误。