SQL에서 가장 중요하다고 생각하는 JOIN에 대해 간단하게 정리해보겠습니다.
기본적으로 데이터들의 중복을 최소화 하기 위해 구성된 테이블들을 제대로 조인해야 원하는 데이터를 출력할 수 있기 때문에 개인적으로는 가장 중요하다고 생각합니다.
<사원 테이블>
NAME | AGE | DEPT_NO |
LEA | 29 | 1 |
PARK | 34 | 4 |
RUY | 22 | 2 |
KIM | 40 | 2 |
CHOI | 33 | 3 |
JIN | 20 | (NULL) |
<부서테이블>
DEPT_NO | DEPT_NAME | TEL |
1 | 인사팀 | 01 |
2 | 개발팀 | 02 |
3 | 영업팀 | 03 |
4 | 기술팀 | 04 |
5 | 임원 | 05 |
1. INNER JOIN
조인중에서 가장 간단한 INNER JOIN은 두 테이블에 특정 컬럼을 비교하여 조건이 일치하는 데이터는 합쳐서 출력을 하게 됩니다.
SELECT EM.NAME AS NAME, EM.AGE AS AGE, DP.DEPT_NO AS DEPT_NO, DP.DEPT_NAME AS DEPT_NAME, DP.TEL AS TEL
FROM 회원 EM INNER JOIN 부서 DP
ON EM.DEPT_NO = DP.DEPT_NO
기본적으로 INNER JOIN에서 INNER는 생략가능합니다.
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 인사팀 | 1 |
PARK | 34 | 4 | 기술팀 | 4 |
RUY | 22 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 영업팀 | 3 |
결과를 보게되면 회원테이블에 JIN사원 정보와 부서테이블에 임원팀 정보가 없는걸 확인 할 수 있습니다.
이처럼 기준이 되는 테이블이 없이 조건에 충족하는 데이터만을 출력하게 됩니다.
( 아래서 다시 설명하겠지만 CROSS JOIN에서 WHERE문을 적용하면 INNER JOIN과 같은 결과를 만들 수 있습니다. )
2. OUTER JOIN
INNER JOIN과는 다르게 OUTER JOIN은 기준이 되는 테이블이 존재합니다.
LEFT OUTER JOIN
SELECT EM.NAME AS NAME, EM.AGE AS AGE, DP.DEPT_NO AS DEPT_NO, DP.DEPT_NAME AS DEPT_NAME, DP.TEL AS TEL
FROM 회원 EM LEFT OUTER JOIN 부서 DP
ON EM.DEPT_NO = DP.DEPT_NO
( OUTER JOIN에서 LEFT, RIGHT, JOIN은 생략이 안되지만 OUTER는 생략가능 ex. LEFT JOIN, RIGHT JOIN )
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 인사팀 | 1 |
RUY | 22 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 영업팀 | 3 |
PARK | 34 | 4 | 기술팀 | 4 |
JIN | 20 | NULL | NULL | NULL |
LEFT OUTER JOIN에 결과를 보시게되면 ON조건에 일치하는 값이 없는 JIN에 데이터도 출력이 되면서 부서 테이블에 컬럼들에는 NULL로 생성이 됩니다.
OUTER JOIN에서 가장 중요한점은 기준이 되는 테이블은 모두 출력이 된다는 점 입니다.
RIGHT OUTER JOIN
SELECT EM.NAME AS NAME, EM.AGE AS AGE, DP.DEPT_NO AS DEPT_NO, DP.DEPT_NAME AS DEPT_NAME, DP.TEL AS TEL
FROM 회원 EM RIGHT OUTER JOIN 부서 DP
ON EM.DEPT_NO = DP.DEPT_NO
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 인사팀 | 1 |
PARK | 34 | 4 | 기술팀 | 4 |
RUY | 22 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 영업팀 | 3 |
NULL | NULL | 5 | 임원 | 5 |
RIGHT OUTER JOIN에 결과를 보시면 기준이 되는 부서 테이블은 모두 출력이 되면서 임원 컬럼에 연결되는 사원이 없기때문에 NULL로 붙게되며 개발팀 부서 사원은 2명이므로 개발팀은 2개의 데이터 출력이 된 모습입니다.
앞서 설명드렸듯이 아우터 조인은 기준이 되는 테이블은 모두 출력이 되며 일치하는 조인조건에 일치하는 값이 없다면 NULL로 붙게되고 일치하는 데이터가 2개 이상이라면 중복으로 출력이 됩니다.
3. OUTER JOIN (+)를 사용한 예제
WHERE 조건절에 (+)가 붙어 있는 쿼리는 아우터 조인을 의미합니다.
SELECT EM.*, DP.*
FROM EEMM EM, DDPP DP
WHERE EM.DEPT_NO = DP.DEPT_NO(+);
FROM절에 JOIN에 대한 모습은 없지만 WHERE조건절에 (+)가 붙어있는 쿼리는 아우터 조인을 의미하며 (+)가 있는 테이블컬럼이 붙는 테이블이며 반대쪽 없는 테이블이 기준이 되는 테이블이 됩니다.
SELECT EM.*, DP.*
FROM EEMM EM LEFT JOIN DDPP DP
ON EM.DEPT_NO = DP.DEPT_NO;
위 두개의 쿼리는 같은 LEFT OUTER JOIN을 의미합니다. WHERE에 (+)는 ON과 같은 JOIN 조건절이고 (+)가 없는 조건절은 일반 WHERE조건절로 보시면 됩니다.
4. FULL OUTER JOIN
SELECT EM.*, DP.*
FROM EEMM EM FULL OUTER JOIN DDPP DP
ON EM.DEPT_NO = DP.DEPT_NO;
FULL OUTER JOIN 조인은 (OUTER 생략가능) 조건에 일치하는 데이터는 합치면서 일치하는 데이터 없는 값들은 서로 NULL로 붙여서 출력을 하게 됩니다.
NAME | AGE | DEPT_NO | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 1 | 인사팀 | 1 |
PARK | 34 | 4 | 4 | 기술팀 | 4 |
RUY | 22 | 2 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 3 | 영업팀 | 3 |
JIN | 20 | NULL | NULL | NULL | NULL |
NULL | NULL | NULL | 5 | 임원 | 5 |
사원테이블에 JIN과 부서테이블에 임원부서를 제외하고 JOIN이 되었지만 아래 두 데이터는 조건에 일치하는 데이터가 없으므로 NULL이 붙어서 모두 출력이 된 모습입니다.
5. NATURAL JOIN
SELECT *
FROM EEMM EM NATURAL JOIN DDPP DP
NATURAL JOIN은 INNER JOIN처럼 값을 비교하여 일치하는 데이터만 출력을 하지만 ON조건절이 없습니다.
DBMS에서 이름과 속성을 비교하여 조인할 컬럼을 자동으로 찾은뒤 조인을 해주게 됩니다.
이때 주의해야할 점은 ON을 사용하면 안되며 SELECT에서 조인이 될 컬럼 앞에 테이블명이나 ALIAS가 붙으면 안됩니다.
( ex. EM.DEPT_NO 또는 DP.DEPT_NO )
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
1 | LEA | 29 | 인사팀 | 1 |
4 | PARK | 34 | 기술팀 | 4 |
2 | RUY | 22 | 개발팀 | 2 |
2 | KIM | 40 | 개발팀 | 2 |
3 | CHOI | 33 | 영업팀 | 3 |
6. USING JOIN
USING JOIN 조인은 INNER JOIN처럼 조건에 일치하는 데이터를 출력하는 조인입니다.
SELECT *
FROM EEMM EM JOIN DDPP DP
USING (DEPT_NO)
ON을 사용하지 않고 USING 안에 두 테이블에서 조인할 컬럼을 넣어주면 됩니다.
이때 주의 사항은 USING 안에 들어갈 컬럼 앞에는 테이블명이나 ALIAS가 들어가면 안되고 SELECT구문에 조인한 컬럼역시 테이블명이나 ALIAS가 들어가면 안됩니다.
( ex. USING(EM.DEPT_NO) , SELECT DP.DEPT_NO )
'sqld' 카테고리의 다른 글
SQLD 사칙연산 (0) | 2024.10.29 |
---|---|
SQLD 정렬 정리 (2) | 2024.10.29 |
계층형 쿼리 (0) | 2024.05.14 |
SQL에서 가장 중요하다고 생각하는 JOIN에 대해 간단하게 정리해보겠습니다.
기본적으로 데이터들의 중복을 최소화 하기 위해 구성된 테이블들을 제대로 조인해야 원하는 데이터를 출력할 수 있기 때문에 개인적으로는 가장 중요하다고 생각합니다.
<사원 테이블>
NAME | AGE | DEPT_NO |
LEA | 29 | 1 |
PARK | 34 | 4 |
RUY | 22 | 2 |
KIM | 40 | 2 |
CHOI | 33 | 3 |
JIN | 20 | (NULL) |
<부서테이블>
DEPT_NO | DEPT_NAME | TEL |
1 | 인사팀 | 01 |
2 | 개발팀 | 02 |
3 | 영업팀 | 03 |
4 | 기술팀 | 04 |
5 | 임원 | 05 |
1. INNER JOIN
조인중에서 가장 간단한 INNER JOIN은 두 테이블에 특정 컬럼을 비교하여 조건이 일치하는 데이터는 합쳐서 출력을 하게 됩니다.
SELECT EM.NAME AS NAME, EM.AGE AS AGE, DP.DEPT_NO AS DEPT_NO, DP.DEPT_NAME AS DEPT_NAME, DP.TEL AS TEL
FROM 회원 EM INNER JOIN 부서 DP
ON EM.DEPT_NO = DP.DEPT_NO
기본적으로 INNER JOIN에서 INNER는 생략가능합니다.
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 인사팀 | 1 |
PARK | 34 | 4 | 기술팀 | 4 |
RUY | 22 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 영업팀 | 3 |
결과를 보게되면 회원테이블에 JIN사원 정보와 부서테이블에 임원팀 정보가 없는걸 확인 할 수 있습니다.
이처럼 기준이 되는 테이블이 없이 조건에 충족하는 데이터만을 출력하게 됩니다.
( 아래서 다시 설명하겠지만 CROSS JOIN에서 WHERE문을 적용하면 INNER JOIN과 같은 결과를 만들 수 있습니다. )
2. OUTER JOIN
INNER JOIN과는 다르게 OUTER JOIN은 기준이 되는 테이블이 존재합니다.
LEFT OUTER JOIN
SELECT EM.NAME AS NAME, EM.AGE AS AGE, DP.DEPT_NO AS DEPT_NO, DP.DEPT_NAME AS DEPT_NAME, DP.TEL AS TEL
FROM 회원 EM LEFT OUTER JOIN 부서 DP
ON EM.DEPT_NO = DP.DEPT_NO
( OUTER JOIN에서 LEFT, RIGHT, JOIN은 생략이 안되지만 OUTER는 생략가능 ex. LEFT JOIN, RIGHT JOIN )
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 인사팀 | 1 |
RUY | 22 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 영업팀 | 3 |
PARK | 34 | 4 | 기술팀 | 4 |
JIN | 20 | NULL | NULL | NULL |
LEFT OUTER JOIN에 결과를 보시게되면 ON조건에 일치하는 값이 없는 JIN에 데이터도 출력이 되면서 부서 테이블에 컬럼들에는 NULL로 생성이 됩니다.
OUTER JOIN에서 가장 중요한점은 기준이 되는 테이블은 모두 출력이 된다는 점 입니다.
RIGHT OUTER JOIN
SELECT EM.NAME AS NAME, EM.AGE AS AGE, DP.DEPT_NO AS DEPT_NO, DP.DEPT_NAME AS DEPT_NAME, DP.TEL AS TEL
FROM 회원 EM RIGHT OUTER JOIN 부서 DP
ON EM.DEPT_NO = DP.DEPT_NO
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 인사팀 | 1 |
PARK | 34 | 4 | 기술팀 | 4 |
RUY | 22 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 영업팀 | 3 |
NULL | NULL | 5 | 임원 | 5 |
RIGHT OUTER JOIN에 결과를 보시면 기준이 되는 부서 테이블은 모두 출력이 되면서 임원 컬럼에 연결되는 사원이 없기때문에 NULL로 붙게되며 개발팀 부서 사원은 2명이므로 개발팀은 2개의 데이터 출력이 된 모습입니다.
앞서 설명드렸듯이 아우터 조인은 기준이 되는 테이블은 모두 출력이 되며 일치하는 조인조건에 일치하는 값이 없다면 NULL로 붙게되고 일치하는 데이터가 2개 이상이라면 중복으로 출력이 됩니다.
3. OUTER JOIN (+)를 사용한 예제
WHERE 조건절에 (+)가 붙어 있는 쿼리는 아우터 조인을 의미합니다.
SELECT EM.*, DP.*
FROM EEMM EM, DDPP DP
WHERE EM.DEPT_NO = DP.DEPT_NO(+);
FROM절에 JOIN에 대한 모습은 없지만 WHERE조건절에 (+)가 붙어있는 쿼리는 아우터 조인을 의미하며 (+)가 있는 테이블컬럼이 붙는 테이블이며 반대쪽 없는 테이블이 기준이 되는 테이블이 됩니다.
SELECT EM.*, DP.*
FROM EEMM EM LEFT JOIN DDPP DP
ON EM.DEPT_NO = DP.DEPT_NO;
위 두개의 쿼리는 같은 LEFT OUTER JOIN을 의미합니다. WHERE에 (+)는 ON과 같은 JOIN 조건절이고 (+)가 없는 조건절은 일반 WHERE조건절로 보시면 됩니다.
4. FULL OUTER JOIN
SELECT EM.*, DP.*
FROM EEMM EM FULL OUTER JOIN DDPP DP
ON EM.DEPT_NO = DP.DEPT_NO;
FULL OUTER JOIN 조인은 (OUTER 생략가능) 조건에 일치하는 데이터는 합치면서 일치하는 데이터 없는 값들은 서로 NULL로 붙여서 출력을 하게 됩니다.
NAME | AGE | DEPT_NO | DEPT_NO | DEPT_NAME | TEL |
LEA | 29 | 1 | 1 | 인사팀 | 1 |
PARK | 34 | 4 | 4 | 기술팀 | 4 |
RUY | 22 | 2 | 2 | 개발팀 | 2 |
KIM | 40 | 2 | 2 | 개발팀 | 2 |
CHOI | 33 | 3 | 3 | 영업팀 | 3 |
JIN | 20 | NULL | NULL | NULL | NULL |
NULL | NULL | NULL | 5 | 임원 | 5 |
사원테이블에 JIN과 부서테이블에 임원부서를 제외하고 JOIN이 되었지만 아래 두 데이터는 조건에 일치하는 데이터가 없으므로 NULL이 붙어서 모두 출력이 된 모습입니다.
5. NATURAL JOIN
SELECT *
FROM EEMM EM NATURAL JOIN DDPP DP
NATURAL JOIN은 INNER JOIN처럼 값을 비교하여 일치하는 데이터만 출력을 하지만 ON조건절이 없습니다.
DBMS에서 이름과 속성을 비교하여 조인할 컬럼을 자동으로 찾은뒤 조인을 해주게 됩니다.
이때 주의해야할 점은 ON을 사용하면 안되며 SELECT에서 조인이 될 컬럼 앞에 테이블명이나 ALIAS가 붙으면 안됩니다.
( ex. EM.DEPT_NO 또는 DP.DEPT_NO )
결과)
NAME | AGE | DEPT_NO | DEPT_NAME | TEL |
1 | LEA | 29 | 인사팀 | 1 |
4 | PARK | 34 | 기술팀 | 4 |
2 | RUY | 22 | 개발팀 | 2 |
2 | KIM | 40 | 개발팀 | 2 |
3 | CHOI | 33 | 영업팀 | 3 |
6. USING JOIN
USING JOIN 조인은 INNER JOIN처럼 조건에 일치하는 데이터를 출력하는 조인입니다.
SELECT *
FROM EEMM EM JOIN DDPP DP
USING (DEPT_NO)
ON을 사용하지 않고 USING 안에 두 테이블에서 조인할 컬럼을 넣어주면 됩니다.
이때 주의 사항은 USING 안에 들어갈 컬럼 앞에는 테이블명이나 ALIAS가 들어가면 안되고 SELECT구문에 조인한 컬럼역시 테이블명이나 ALIAS가 들어가면 안됩니다.
( ex. USING(EM.DEPT_NO) , SELECT DP.DEPT_NO )
'sqld' 카테고리의 다른 글
SQLD 사칙연산 (0) | 2024.10.29 |
---|---|
SQLD 정렬 정리 (2) | 2024.10.29 |
계층형 쿼리 (0) | 2024.05.14 |