MySQL을 사용하고 있습니까?


252

MySQL JOIN에서 ON와 의 차이점은 무엇 USING()입니까? 내가 알 수있는 한 USING(), 더 편리한 구문이지만 ON열 이름이 동일하지 않을 때 약간 더 유연합니다. 그러나 그 차이는 너무 작기 때문에을 사용하지 않을 것이라고 생각할 것입니다 USING().

눈을 만나는 것보다 더 많은 것이 있습니까? 그렇다면 주어진 상황에서 어떤 것을 사용해야합니까?


1
또한 자연 가입이있다 : stackoverflow.com/questions/8696383/…
— allyourcode

참고 using또 다른 사용법을 가지고, 게다가 합류했다. 참조 stackoverflow.com/a/13750399/632951
— Pacerier

답변:


400

그것은 주로 구문 설탕이지만 몇 가지 차이점이 주목됩니다.

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>

2
구문상의 차이에 대한 +1 좋은 답변. 성능 차이가 궁금합니다. 나는로 USING해석 한다고 상상 한다 ON.
— Jason McCreary

9
사실, 둘 다 평범한 오래된 세타 스타일로 해석됩니다. 쿼리에서 EXPLAIN EXTENDED를 호출 한 다음 SHOW WARNINGS를 호출하면 알 수 있습니다.
— Shlomi Noach

2
복합 기본 키로 결합 할 때 유용한 field_id USING(범주 를 수행 할 수도 있습니다. 또한 최적화 프로그램이 경우에 따라 성능을 향상시키는 데 사용한다고 들었습니다.,)USING
— Timo Huovinen

가 USINGMySQL의 정의 또는 표준입니까?
— PhoneixS


18

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)
; 

4
매우 좋은 지적입니다. 모든 장점이 using제공 하는 것 중에서 다른 술어와 결합 할 수는 없습니다 select*from t join t2 using(i) and on 1.
— Pacerier

where hasAirport ;- 이것은 무엇을 의미 하는가 ? 비교할 값이 없습니다.
— Istiaque Ahmed

또한 =보다 ON을 사용하여 더 많은 비교를 할 수 있습니다. 마찬가지로 SELECT * FROM country LEFT JOIN city ON country.countryId=city.countryId AND city.city BETWEEN 'C' AND 'E' 모든 국가를 제외하고 C 또는 D로 시작하는 도시 만 표시합니다 (있는 경우). (플러스 타운은 'E')
— Roemer

나는 심지어 ON에서 하위 쿼리로 JOIN을 했었습니다! 그것은 가능하고 때로는 매우 효과적입니다.
— Roemer

11

Wikipedia 에는 다음과 같은 정보가 있습니다 USING.

그러나 USING 구문은 단순한 구문 설탕 그 이상입니다. 결과 집합이 명시 적 술어가있는 버전의 결과 집합과 다르기 때문입니다. 특히 USING 목록에 언급 된 모든 열은 조인의 각 테이블에 대해 한 번이 아니라 규정되지 않은 이름으로 한 번만 나타납니다. 위의 경우 단일 DepartmentID 열이 있고 employee.DepartmentID 또는 department.DepartmentID가 없습니다.

그것이 말한 테이블 :

여기에 이미지 설명을 입력하십시오

포스트 그레스의 문서도 꽤 잘들을 정의한다 :

ON 절은 가장 일반적인 종류의 조인 조건입니다. WHERE 절에 사용 된 것과 같은 종류의 부울 값식이 사용됩니다. ON 표현식이 true로 평가되면 T1 및 T2의 행 쌍이 일치합니다.

USING 절은 조인의 양쪽에서 동일한 이름을 조인 열에 사용하는 특정 상황을 활용할 수있는 축약 형입니다. 쉼표로 구분 된 공유 열 이름 목록을 사용하고 각 항목에 대한 동등 비교를 포함하는 결합 조건을 형성합니다. 예를 들어, T1과 T2를 USING (a, b)과 결합하면 결합 조건이 ON T1.a = T2.a AND T1.b = T2.b가됩니다.

또한 JOIN USING의 출력은 중복 열을 억제합니다. 일치하는 열을 모두 같은 값을 가져야하므로 인쇄 할 필요가 없습니다. JOIN ON은 T1에서 모든 열을 생성하고 T2에서 모든 열을 생성하는 반면, JOIN USING은 나열된 각 열 쌍 (목록 순서대로)에 대해 하나의 출력 열을 생성 한 다음 T1의 나머지 열, T2의 나머지 열을 생성합니다. .


1

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 버그 일 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.