본문 바로가기
IT Programming/Oracle

[Oracle] 쿼리의 조인 VOL.1) INNER JOIN , OUTER JOIN

by Euniieunii 2023. 4. 19.

[ Query JOIN ]

쿼리에서 JOIN 은 아주 유용하고 중요한 기능이다. 앞서 조회쿼리 시 유의사항에서도 작성했듯 여러모로 자주 사용된다.

JOIN : 두 개 이상의 데이터베이스 테이블을 결합하여 하나의 결과 집합을 만드는 데 사용.

JOIN은 기본적으로 이렇게 작성이 된다.

//JOIN 기본 작성법
SELECT [칼럼1, 칼럼2, ...]
FROM [테이블1]
JOIN [테이블2] ON [테이블1.공통필드] = [테이블2.공통필드]

//[칼럼1, 칼럼2, ...]: 검색하려는 데이터의 필드 목록, 
//[테이블1]과 [테이블2]: 검색 대상이 되는 두 개의 테이블 이름 
// ON 절은 두 개의 테이블에서 공통으로 사용되는 필드를 지정 
// -> 이 공통필드를 기준으로 JOIN이 수행되며, 
// -> 결과는 두 개의 테이블에서 해당 필드가 일치하는 모든 레코드를 결합한 것이다.

하지만 JOIN 은 기본 말고도 여러 가지 종류가 있어서 조금 헷갈릴 수 있다. 우선 가장 일반적으로 사용되는 JOIN 종류들 중에서 3가지, INNER JOIN/ LEFT JOIN/ RIGHT JOIN 의 작성법을 정리하였다.


(1) INNER JOIN

//INNER JOIN 작성법

SELECT [칼럼1, 칼럼2, ...]
FROM [테이블1]
INNER JOIN [테이블2] ON [테이블1.공통필드] = [테이블2.공통필드]

INNER JOIN: 두 개의 테이블에서 공통된 값을 가진 레코드만 선택하여 결과 출력

< INNER JOIN 사진 참고: 출처: 혼공 hongong.hanbit.co.kr >

 

(2) OUTER JOIN

//LEFT OUTER JOIN 작성법

SELECT [칼럼1, 칼럼2, ...]
FROM [테이블1]
LEFT JOIN [테이블2] ON [테이블1.공통필드] = [테이블2.공통필드]

LEFT JOIN: 왼쪽 테이블의 모든 레코드와 오른쪽 테이블에서 일치하는 값을 가진 레코드를 선택하여 결과 출력

//RIGHT OUTER JOIN 작성법

SELECT [칼럼1, 칼럼2, ...]
FROM [테이블1]
RIGHT JOIN [테이블2] ON [테이블1.공통필드] = [테이블2.공통필드]

RIGHT JOIN: 오른쪽 테이블의 모든 레코드와 왼쪽 테이블에서 일치하는 값을 가진 레코드를 선택하여 결과 출력

< OUTER JOIN 사진 참고: 출처: 혼공 hongong.hanbit.co.kr >

  • INNER JOIN 은 두 테이블에 모두 데이터가 있어야 하지만 OUTER JOIN은 한쪽에만 데이터가 있어도 결과가 나온다
  • FULL OUTER JOIN: 왼쪽 또는 오른쪽 테이블의 모든 값이 출력되는 조인
  • LEFT OUTER JOIN: 오른쪽 테이블에 일치하는 레코드가 없는 경우에도 왼쪽 테이블의 레코드를 유지하며, 오른쪽 테이블의 모든 레코드에 대해 NULL 값을 반환한다.
  • RIGHT OUTER JOIN: 왼쪽 테이블에 일치하는 레코드가 없는 경우에도 오른쪽 테이블의 레코드를 유지하며, 왼쪽쪽 테이블의 모든 레코드에 대해 NULL 값을 반환한다.
+ OUTER JOIN을 할 때 별칭을 사용한다면, JOIN절 뒤 ON의 공통필드에 해당하는 칼럼에는 별칭을 붙이면 안된다. 

++ 추가적으로 오라클에서만 지원하는 OUTER 조인의 방법이 있다. ++

[ 오라클에서만 지원하는 LEFT / RIGHT OUTER JOIN ]
- LEFT OUTER JOIN : WHERE 테이블 A 의 컬럼 = 테이블 B의 컬럼 (+)
- RIGHT OUTER JOIN : WHERE 테이블 A 의 컬럼 (+) = 테이블 B의 컬럼

이 외에도 Join 에는 여러 종류가 있는데, 그 중 일부까지 합하여 간략하게 표로 정리하였다.

<.JOIN의 종류 표 >


마지막으로는 지금까지 이야기를 한 내용들을 예제로 풀어보았다.

 

< 예제 1 >

--1. 학점이 2학점인 과목과 이를 강의하는 교수를 검색한다
SELECT C.CNAME
    , C.ST_NUM
    , P.PNAME
    , P.PNO
    FROM COURSE C
    JOIN PROFESSOR P
    ON P.PNO = C.PNO
    WHERE C.ST_NUM =2.0;
   

--2. 화학과 교수가 강의하는 과목을 검색한다
SELECT P.PNAME
    , P.PNO
    , P.SECTION
    , C.PNO
    FROM PROFESSOR P
    JOIN COURSE C
    ON P.PNO = C.PNO
    WHERE SECTION = '화학';
  

--3. 화학과 1학년 학생의 기말고사 성적을 검색한다
SELECT DISTINCT SC.SNO
    ,  S.SYEAR
    ,  S.SNAME
    ,  S.MAJOR
    ,  SC.RESULT
    FROM STUDENT S
    JOIN SCORE SC
    ON S.SNO = SC.SNO
    AND S.SYEAR =1 AND S.MAJOR = '화학';
   
--4. 일반화학 과목의 기말고사 점수를 검색한다
SELECT C.CNAME
    , S.CNO
    , S.RESULT
    FROM COURSE C
    JOIN SCORE S
    ON C.CNO = S.CNO
    AND C.CNAME = '일반화학';
    

--5. 화학과 1학년 학생의 일반화학 기말고사 점수를 검색한다
SELECT ST.SNAME
    , ST.MAJOR
    , ST.SYEAR
    , C.CNAME
    , S.CNO
    , S.RESULT
    FROM COURSE C
    JOIN STUDENT ST
    ON ST.MAJOR = '화학' AND ST.SYEAR = 1
    JOIN SCORE S
    ON C.CNO = S.CNO
    AND C.CNAME = '일반화학';

--6. 화학과 1학년 학생이 수강하는 과목을 검색한다
SELECT ST.SNAME
    , ST.SYEAR
    , ST.MAJOR
    , C.CNAME
    FROM STUDENT ST
    JOIN COURSE C
    ON ST.MAJOR = '화학' AND ST.SYEAR = 1;

--7. 유기화학 과목의 평가점수가 F인 학생의 명단을 검색한다
SELECT ST.*
    ,C.CNO
    ,C.CNAME
    ,SG.GRADE
    FROM STUDENT ST
    JOIN SCORE SC
    ON ST.SNO = SC.SN
    JOIN COURSE C
    ON SC.CNO = C.CNO
    JOIN SCGRADE SG
    ON SC.RESULT BETWEEN LOSCORE AND HISCORE
    AND GRADE = 'F'
    AND C.CNAME = '유기화학';

 

< 예제 2 >

--1. 유기화학과목 수강생의 기말고사 시험점수를 검색하라
SELECT DISTINCT SC.CNO
    ,  C.CNO
    ,  C.CNAME 
    ,  SC.RESULT
    FROM COURSE C
    JOIN SCORE SC
    ON C.CNO = SC.CNO
    AND C.CNAME = '유기화학';
    

--2. 화학과 학생이 수강하는 과목을 담당하는 교수의 명단을 검색하라
SELECT DISTINCT S.SNAME
    , S.SYEAR
    , S.MAJOR
    , P.PNAME AS 교수명
    FROM PROFESSOR P
    JOIN STUDENT S
    ON S.MAJOR = '화학';

--3. 모든 교수의 명단과 담당 과목을 검색한다
SELECT P.PNAME
    , C.CNAME
    FROM PROFESSOR P
    JOIN COURSE C
    ON P.PNO = C.PNO;

--4. 모든 교수의 명단과 담당 과목을 검색한다(단 모든 과목도 같이 검색한다)
SELECT P.PNAME
    , C.CNAME
    FROM PROFESSOR P
    LEFT OUTER JOIN COURSE C
    ON P.PNO = C.PNO;

댓글