MySQL - JOIN

김소희·2024년 8월 9일

MySQL

목록 보기
4/17

JOIN

SQL 이용하여 두 개의 테이블을 연결해 데이터 조회하는 것을 JOIN이라고 한다. 두 테이블 연결 작업이므로 이를 위한 연결고리가 필요하다. JOIN 칼럼은 두 테이블에서 같은 값을 가진 칼럼을 의미한다.

JOIN의 특징

  • JOIN 테이블은 서로 값은 값을 가진 칼럼이 존재해야 한다.
  • 2개 이상의 테이블 JOIN 가능하다.
  • JOIN 할 때 테이블에 대한 별칭을 사용한다.
  • JOIN 시 조건이 필요하다

JOIN의 종류

(INNER) JOIN

  • A 테이블과 B 테이블의 교집합을 생각하면 된다.
  • (A ∩ B)
  • 조인하는 테이블의 ON 절의 조건이 일치하는 결과만 출력
  • 표준 SQL과는 달리 MySQL에서는 JOIN, INNER JOIN, CROSS JOIN이 모두 같은 의미로 사용된다.

-- 예시1
SELECT *
FROM A AS a
JOIN B AS b
ON a.KEY = b.KEY;
select u.userid, name 
from usertbl as u inner join buytbl as b 
on u.userid=b.userid 
where u.userid="111" -- join을 완료하고 그다음 조건을 따진다.

A, B 각각 테이블 1과 2 그리고 KEY를 COL1이라 보면 된다. 각 테이블에서 JOIN KEY COL1 값이 존재하는 데이터만 가져온 것을 확인할 수 있다.

inner join 함축 구문

select u.userid, name 
from usertbl u, buytbl b 
where u.userid=b.userid and u.userid="111"
  • 뒤에서 배울 left outer join은 1 : N 관계에서 어느 테이블을 기준으로 left할 것이냐에 따라, 레코드 갯수가 달리지게 된다. 그리고 또한 조인에 부합되지 않는 레코드는 테이블 기준에 따라 남기도 한다.
    `
  • 하지만 inner join 은 어느 테이블에서 기준으로 조인하든 조인 관계에 부합되는 레코드를 모두 가지게 된다. 그리고 조인에 부합되지 않는 레코드는 모두 삭제 된다.

LEFT JOIN

LEFT JOIN은 두 테이블이 있을 경우, 첫 번째 테이블을 기준으로 두 번째 테이블을 조합하는 JOIN이다.

-- 예) 1학년 학생의 이름과 지도교수명을 출력하라. 단, 지도교수가 지정되지 않은 학생도 출력되게 하라.

SELECT STUDENT.NAME, PROFESSOR.NAME 
FROM STUDENT LEFT OUTER JOIN PROFESSOR -- STUDENT를 기준으로 왼쪽 조인
ON STUDENT.PID = PROFESSOR.ID 
WHERE GRADE = 1

LEFT JOIN을 여러번 할 때 주의할 점

  • INNER JOIN과는 달리 LEFT JOIN은 조인하는 테이블의 순서가 상당히 중요하다. 어떤 순서로 테이블을 조인하는지에 따라 결과 테이블에 조회되는 행의 개수며 구성 등이 달라질 수 있다. 따라서 JOIN 문을 작성할 때, 만약 LEFT JOIN을 할 거라면 가장 첫 번째의 테이블로 SELECT문에 가장 많은 열을 가져와야 할 테이블을 우선으로 적어준다.
    `
  • 조인을 여러 번 해야하는데 시작을 LEFT JOIN으로 했다면 나머지 조인도 LEFT JOIN을 이어나간다.즉, LEFT JOIN을 쓰다가 갑자기 INNER JOIN 이나 다른 조인을 사용하지 않는다는 이야기다.

RIGHT JOIN

RIGHT JOIN은 두 테이블이 있을 경우, 두 번째 테이블을 기준으로 첫 번째 테이블을 조합하는 JOIN이다.

-- 예) 1학년 학생의 이름과 지도교수명을 출력하라. 단, 지도교수가 지정되지 않은 학생도 출력되게 하라.

SELECT STUDENT.NAME, PROFESSOR.NAME 
FROM STUDENT RIGHT OUTER JOIN PROFESSOR -- PROFESSOR를 기준으로 오른쪽 조인
ON STUDENT.PID = PROFESSOR.ID 
WHERE GRADE = 1

JOIN에서 중복된 레코드 제거하기

Distinct 사용

  • mysql에서 지원하는 distinct 문법을 사용하면 된다.
  • 매우 쉬운 방법이지만 레코드 수가 많은 경우 성능이 느리다는 단점이 있다.
 -- DISTINCT를 추가
 SELECT DISTINCT person.id, person.name, job.job_name 
 FROM person INNER JOIN job 
 ON person.name = job.person_name;

JOIN 전에 중복을 제거하기

  • 앞서 말한 것처럼 SELECT DISTINCT는 간단하지만 성능이 느리다.
  • 성능을 위해서는 JOIN 전에 중복을 제거하는 작업을 해주는 것이 좋다. (물론 더 좋은 것은 중복이 없도록 테이블 설계를 잘 하는 것이다)

JOIN 전에 중복 제거는 다음과 같이 조인할 테이블에 서브쿼리의 inline view를 사용해 distinct 하고 조인하면 된다.

select A.name, A.countryCode 
from city A 
left join ( select distinct name, Code from country ) as B 
-- 조인할 테이블에 먼저 distinct로 중복을 제거한 select문을 서브쿼리로 불러와 임시테이블로 만든뒤 조인한다
on A.countrycode = B.Code

언뜻보면 복잡해보일 수 있고 성능이 더 느려보일 수 있는데, 일반적으로 레코드 수가 많은 경우 JOIN 전에 중복을 제거해서 1:1 JOIN으로 바꾸는 것이 훨씬 빠르다.
물론 WHERE 절에 조건이 존재 여부, index 존재 여부, 한쪽 테이블의 크기가 엄청 적은 경우 등등 많은 시나리오가 있으니 성능 비교를 하는 것이 좋다.

0개의 댓글