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.