본문 바로가기
스터디/SQL

[정리노트] SQLD 2024년 개정판 - 표준조인

by 견습생L 2024. 8. 21.

 

[정리노트] SQLD 2024년 개정판 - 표준조인


표준 조인

  •   ANSI 표준으로 작성되는 INNER JOIN, CROSS JOIN, NATURAL JOIN, OUTER JOIN을 말함

INNER JOIN

  •   내부 조인이라고 하며, 조인 조건이 일치하는 행만 추출 (Oracle 조인 기본)
  •   ANSI 표준의 경우 FROM 절에 INNER JOIN 혹은 줄여서 JOIN 명시
  •   ANSI 표준의 경우 USING 이나 ON 조건절을 필수적으로 사용

ON

  •   조인할 양 컬럼의 컬럼명 나타냄 (서로 다르더라도 사용 가능)
  •   ON 조건의 괄호는 옵션(생략 가능)
  •   컬럼명이 같을 경우 테이블 이름이나 별칭을 사용하여 명확하게 지정 (테이블 출처 명확히)
  •   ON 조건절에서 조인조건 명시, WHERE 절에서는 일반조건 명시 (WHERE 절과 ON 절을 쓰임에 따라 명확히 구분)
  •   문법
SELECT 테이블1.컬럼명, 테이블2.컬럼명
  FROM 테이블1 INNER JOIN 테이블2
    ON 테이블1.조인컬럼 = 테이블2.조인컬럼;

ex) EMP테이블과 DEPT 테이블을 사용하여 각 직원의 이름과 부서명을 함께 출력 (EQUI JOIN)

SELECT EMP.ENAME, DEPT.DNAME
	FROM EMP JOIN DEPT
		ON EMP.DEPTNO = DEPT.DEPTNO;

→ Oracle 표준은 FROM 절에 테이블을 컴마로 구분, WHERE 절에 조인 조건 나열
→ Oracle은 INNER JOIN이 기본 조인 연산이므로 별도의 문법 존재 안함


USING

  •   조인할 컬럼명이 같을 경우
  •   Alias나 테이블 이름 같은 접두사 붙이기 불가
  •   괄호 필수
  •   문법
SELECT 테이블1.컬럼명, 테이블2.컬럼명
  FROM 테이블1 INNER JOIN 테이블2
 USING (동일 컬럼명);

ex) USING 절을 이용한 사원이름과 부서이름 조인

SELECT EMP.ENAME, DEPT.DNAME
  FROM EMP JOIN DEPT
 USING (DEPTNO);


NATURAL JOIN

  •   두 테이블 간의 동일한 이름을 가지는 모든 컬럼들에 대해 EQUI JOIN을 수행
  •   USING, ON, WHERE 절에서 조건 정의 불가
  •   JOIN에 사용된 컬럼들은 데이터 유형이 동일해야 하며 접두사 사용 불가
  •   문법
SELECT 테이블1.컬럼명, 테이블2.컬럼명
  FROM 테이블1 NATURAL JOIN 테이블2;

ex) NATURAL 조인을 이용한 사원 이름, 부서명 출력

SELECT EMP.ENAME, DEPT.DNAME
  FROM EMP NATURAL JOIN DEPT;

예제) NATURAL JOIN 시 주의

SELECT *
  FROM STUDENT NATURAL JOIN PROFESSOR;

→ NATURAL JOIN 은 동일한 이름의 모든 컬럼을 조인 컬럼으로 사용하므로 조인 컬럼의 값이 모두 같을 때만 결과가 리턴됨
→ STUDENT와 PROFESSOR 테이블에는 NAME 컬럼과 PROFNO 컬럼의 컬려명이 서로 동일함


CROSS JOIN

  •   테이블 간 JOIN 조건이 없는 경우 생성 가능한 모든 데이터들의 조합 (Cartesian product(카타시안곱)) 출력
  •   양쪽 테이블 행의 수의 곱한 수의 데이터 조합 발생(m*n)
  •   문법
SELECT 테이블1.컬럼명, 테이블2.컬럼명
  FROM 테이블1 CROSS JOIN 테이블2;

ex) CROSS 조인

SELECT EMP.ENAME, DEPT.DNAME
  FROM EMP CROSS JOIN DEPT;

→ 총 56건이 출력됨 (EMP 14건, DEPT 3건이므로 14x4 =56)


OUTER JOIN

  •   INNER JOIN과 대비되는 조인방식
  •   JOIN 조건에서 동일한 값이 없는 행도 반환할 때 사용
  •   두 테이블 중 한쪽에 NULL을 가지면 EQUI JOIN 시 출력되지 않음 → 이를 출력 시 OUTER JOIN 사용
  •   테이블 기준 방향에 따라 LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN으로 구분
  •   종류
    1. LEFT OUTER JOIN
      •   FROM 절에 나열된 왼쪽 테이블에 해당하는 데이터를 읽은 후, 우측 테이블에서 JOIN 대상 읽어옴
      •   즉, 왼쪽 테이블이 기준이 되어 오른쪽 데이터를 채우는 방식
      •   우측 값에서 같은 값이 없는 경우 NULL 값으로 출력
    2. RIGHT OUTER JOIN
      •   LEFT OUTER JOIN의 반대
      •   오른쪽 테이블이 기준이 되어 왼쪽 데이터를 채우는 방식
      •   FROM 절에 테이블 순서를 변경하면 LEFT OUTER JOIN으로 수행 가
    3. FULL OUTER JOIN
      •   두 테이블 전체 기준으로 결과를 생성하여 중복 데이터를 생성 후 리턴
      •   LEFT OUTER JOIN 결과와 RIGHT OUTER JOIN 결과의 UNION 연산 리턴과 동일함
      •   Oracle 표준에는 없음
    ex) LEFT OUTER JOIN 예제
    •   STUDENT 테이블과 PROFESSOR 테이블을 조인하여 1,4학년 학생들의 이름, 학년, 지도교수 이름 출력

→ STUDENT, PROFESSOR 테이블을 PROFNO로 연결하면 학생,지도교수 정보 함께 출력 가능
→ STUDENT 테이블의 PROFNO가 NULL인 경우는 데이터가 생략됨 (INNER JOIN 수행)
→ 지도교수가 없는 학생 정보 출력 시 OUTER JOIN 수행
→ 이 때, 기준이 도는 데이터(생략되지 않았으면 하는 쪽)는 STUDENT 테이블


LEFT OUTER JOIN

ORACLE 표준)

SELECT *
  FROM STUDENT S, PROFESSOR P
 WHERE S.PROFNO = P.PROFNO(+)
   AND S.GRADE IN (1,4);

→ Oracle 표준은 WHERE 절에 조건을 작성하므로 LEFT OUTER JOIN을 기술하지 X
→ WHERE 절에서 기준이 되는 테이블(STUDENT) 반대 테이블 조건 컬럼 뒤에 (+) 붙임

ANSI 표준)

SELECT S.STUDENT, S.NAME AS 학생명, S.GRADE, S.PROFNO,
        P.PROFNO, P.NAME AS 교수명
  FROM STUDENT S LEFT OUTER JOIN PROFESSOR P
    ON S.PROFNO = P.PROFNO
 WHERE S.GRADE IN (1,4);

→ ANSI 표준에서는 조인의 종류를 FROM 절에 테이블과 테이블 사이 명시
→ 조인 조건을 바로 뒤에 ON절에 나열
→ WHERE 절은 ON 절 밑에 전달(순서 중요)

FULL OUTER JOIN

  •   위 조인 결과를 FULL OUTER JOIN 수행

ANSI 표준)

SELECT S.STUDENT, S.NAME AS 학생명, S.GRADE, S.PROFNO,
        P.PROFNO, P.NAME AS 교수명
  FROM STUDENT S FULL OUTER JOIN PROFESSOR P
    ON S.PROFNO = P.PROFNO;

→ 7004, 7005번 학생 정보는 LEFT OUTER JOIN 에서도, RIGHT OUTER JOIN 에서도 출력됨
→ LEFT OUTER JOIN 결과와 RIGHT OUTER JOIN 결과를 동시 출력 (중복 데이터는 한번만)
→ Oracle 에서는 지원하지 않는 문법 ((+) 기호를 양 방향 전달 시 에러 발생)
→ 성능적으로는 좋지 않기 때문에 사용 시 주의 필요

Oracle 표준)

SELECT S.STUDENT, S.NAME AS 학생명, S.GRADE, S.PROFNO,
       P.PROFNO, P.NAME AS 교수명
  FROM STUDENT S, PROFESSOR P
 WHERE S.PROFNO = P.PROFNO(+)
 UNION
SELECT S.STUDENT, S.NAME AS 학생명, S.GRADE, S.PROFNO,
        P.PROFNO, P.NAME AS 교수명
  FROM STUDENT S, PROFESSOR P
 WHERE S.PROFNO(+) = P.PROFNO;

반응형