본문 바로가기
SQL

JOIN

by csue 2021. 8. 8.

JOIN

조인이란 두 개 이상의 테이블들을 연결 또는 결합하여 데이터를 출력하는 것을 의미한다. 일반적인 경우 PK 와 FK 값의 연관에 의해 조인이 이루어지며 두 값과 연관없이 조인이 이루어지는 경우도 있다.

일반 집합 연산자와 SQL의 비교

일반 집합 연산자 SQL 문 설명
UNION UNION 합집합
합집합에서 생기는 중복을 없애기 위해 UNION 을 사용하고,
중복을 제거하지 않고 표현하기 위해 UNION ALL 을 사용한다.

UNION 과 UNION ALL 의 결과가 같다면 응답 속도 및 효율화의 측면에서 정렬 작업을 시행하지 않는 UNION ALL 을 사용하는 편이 좋다. 
INTERSECTION INTERSECT 교집합
DIFFERENCE EXCEPT
(오라클은 MINUS)
차집합
PRODUCT 연산 CROSS JOIN 곱집합
JOIN 조건이 없는 경우 생길 수 있는 모든 데이터의 조합을 의미한다. (=경우의 수)

조인의 형태

아래는 예시로 사용할 EMP 테이블과 BONUS 테이블이다.

emp
bonus

INNER JOIN

JOIN 조건에서 동일한 값이 있는 행만 반환한다.

SELECT A.ENAME AS "이름",
       A.JOB AS "직업",
       B.SAL AS "연봉",
       B.COMM AS "보너스"
FROM EMP A, BONUS B
WHERE A.ENAME = B.ENAME
ORDER BY A.ENAME ASC;

NATURAL JOIN

두 테이블 간에 동일한 이름을 갖는 모든 컬럼들에 대해 =(EQUI) JOIN 을 수행한다.

NATURAL JOIN 은 두 테이블이 공통적으로 가지고 있는 컬럼으로 자동으로 조인된다. 조인에 사용된 컬럼에는 alias 를 주면 안된다. alias 를 주게 될 경우 column used in NATURAL join cannot have qualifier 라는 에러 메시지를 띄운다.

EMP 테이블과 BONUS 테이블은 ENAME, JOB, SAL 컬럼을 공통으로 가지고 있으므로 자동으로 조인된다. 결과는 INNER JOIN 과 같다.

SELECT ENAME AS "이름",
       JOB AS "직업",
       SAL AS "연봉",
       B.COMM AS "보너스"
FROM EMP A NATURAL JOIN BONUS B
ORDER BY ENAME ASC;

USING 조건절

NATURAL JOIN 에서는 모든 일치되는 컬럼들에 대해서만 JOIN 이 이루어지지만, FROM 절의 USING 조건절을 사용하면 같은 이름을 가진 컬럼들 중에서 원하는 컬럼에 대해서만 선택적으로 EQUI JOIN 을 할 수 있다.

USING 절에 두 테이블이 공통적으로 가지고 있는 컬럼을 기재하며, 해당 컬럼에는 NATURAL JOIN 과 마찬가지로 alias 를 사용할 수 없다.

위에서 말했듯 EMP 테이블과 BONUS 테이블은 ENAME, JOB, SAL 컬럼을 공통으로 가지고 있다.

각각의 컬럼으로 USING 절을 이용한 JOIN 을 해보자.

먼저 ENAME 컬럼을 사용하였을 때, 결과는 아래와 같다.

SELECT ENAME AS "이름",
       A.JOB AS "직업",
       A.SAL AS "연봉",
       B.COMM AS "보너스"
FROM EMP A JOIN BONUS B USING (ENAME)
ORDER BY ENAME ASC;

JOB 컬럼을 사용하였을 때의 결과는 아래와 같다.

JOB 컬럼이 가지고 있는 모든 CROSS JOIN 경우의 수가 나오게 된다.

SELECT A.ENAME AS "이름",
       JOB AS "직업",
       A.SAL AS "연봉",
       B.COMM AS "보너스"
FROM EMP A JOIN BONUS B USING (JOB)
ORDER BY A.ENAME ASC;

SAL 컬럼을 기준으로 하였을 때 결과는 아래와 같다.

SELECT A.ENAME AS "이름",
       A.JOB AS "직업",
       SAL AS "연봉",
       B.COMM AS "보너스"
FROM EMP A JOIN BONUS B USING (SAL)
ORDER BY A.ENAME ASC;

ON 조건절

JOIN 서술부와 비 JOIN 서술부를 분리하여, 컬럼영이 다르더라도 JOIN 조건을 사용할 수 있으며 이해하기가 쉬워진다는 장점이 있다.

ANSI 방식의 JOIN

ANSI JOIN 은 JOIN 정보를 ON절에 기술하여 조건을 명확하게 지정하고, 다른 조건에 대해서는 WHERE 구문에서 지정하는 방식을 의미한다. JOIN사용 후ON(where) 조건절을 사용한 다음 다음 다시JOIN으로 묶어준다고 이해하면 편하다.

EMP 테이블과 BONUS 테이블, 그리고 추가로 DEPT 테이블을 ANSI 방식으로 JOIN 해보자.

DEPT 테이블은 아래와 같이 구성되어 있으며 EMP 테이블과 DEPTNO 컬럼을 공유한다.

DEPT

SELECT A.ENAME AS "이름",
       A.JOB AS "직업",
       A.SAL AS "연봉",
       B.COMM AS "보너스",
       C.DNAME AS "부서이름",
       C.LOC AS "장소"
FROM EMP A
JOIN BONUS B ON (A.ENAME = B.ENAME)
JOIN DEPT C ON (A.DEPTNO = C.DEPTNO)
ORDER BY A.ENAME ASC;

OUTER JOIN

JOIN 조건에서 동일한 값이 없는 행도 반환할 때 사용할 수 있다.

LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN 등의 종류가 있다. 집합군의 모습은 아래와 같다.

집합 연산자

UNION 합집합
중복되는 행은 하나만 출력한다.
UNION ALL 합집합.
중복되는 행에 대한 거름망 없이 출력한다.
UNION 과 UNION ALL 의 결과가 같은 경우 UNION ALL 이 효율적이다.
INTERSECT 교집합
중복되는 행은 하나만 출력한다.
EXCEPT = MINUS 차집합
오라클에서는 MINUS 를 사용한다.

차집합의 예시

SELECT * FROM EMP A
MINUS SELECT * FROM EMP A WHERE A.JOB = 'SALESMAN'
MINUS SELECT * FROM EMP A WHERE A.DEPTNO = '1'

'SQL' 카테고리의 다른 글

서브 쿼리  (0) 2021.09.27
계층형 쿼리  (0) 2021.08.16
GROUP BY, HAVING, ORDER BY  (0) 2021.08.08
함수(Function)  (0) 2021.07.11
SQL 명령어 :: WHERE  (0) 2021.07.11