본문 바로가기

데이터베이스(DB)/Oracle
[Oracle] 조인(JOIN)

// JOIN


- (서로 관계를 맺은) 2개(1개) 이상의 테이블을 사용해서 1개의 결과셋을 만드는 연산

- 테이블A + 테이블B = 테이블C

1. CROSS JOIN

2. INNER JOIN

3. OUTER JOIN

4. SELF JOIN


// CROSSJOIN

- 카티션곱, 데카르트곱

- A 테이블 레코드 개수 X B 테이블 레코드 개수 = 결과셋 레코드 개수

- A 테이블 컬럼 개수 + B 테이블 컬럼 개수 = 결과셋 컬럼 개수

- 쓸모가 없다. > 가치 있는 행과 가치 없는 행이 섞여 있음.

- 개발용, 테스트용으로 사용 > 유효성과 상관 없이 다량의 데이터를 만들 때

select 컬럼리스트 from 테이블A cross join 테이블B   > ANSI-SQL(표준 SQL) > 권장

select 컬럼리스트 from 테이블A, 테이블B             > Oracle 전용



왼쪽 테이블의 첫 번째 레코드 + 오른쪽 테이블의 첫 번째 레코드 > 첫 번째 레코드
                                            ....
왼쪽 테이블의 첫 번째 레코드 + 오른쪽 테이블의 n 번째 레코드 > n 번째 레코드
                                            ....
왼쪽 테이블의 n 번째 레코드 + 오른쪽 테이블의 n 번째 레코드 > (왼쪽 테이블 레코드 수 X 오른쪽 테이블 레코드 수) 번째 레코드


select * from tblCustomer cross join tblSales;

// INNER JOIN

- 참조키를 기준으로 일치하는 행만 조인 

- 관계가 있는 레코드들만 합치는 조인

- 단순 조인에서 유효한 레코드만 추출하는 조인

- 부모 자식 관계의 테이블이 아니어도 동작한다. (다만 결과가 의미 없을 확률이 높다.)

- 컬럼명을 식별하기 위해 테이블명을 적절히 사용한다.
    ~ SELECT NOTICE.ID, NOTICE.NAME, MEMBER.NAME FROM MEMBER INNER JOIN NOTICE ON MEMBER.ID = NOTICE.WRITER_ID

- 컬럼을 지정하는 식별자를 줄이기 위해 테이블의 별칭을 사용한다.
    ~ SELECT N.ID, N.NAME, M.NAME FROM MEMBER INNER JOIN NOTICE ON M.ID = N.WRITER_ID

select 컬럼리스트 from 테이블A inner join 테이블B on 테이블A.컬럼 = 테이블B.컬럼;	> ANSI-SQL(표준 SQL) > 권장
        
select
    컬럼리스트
from 테이블A 
    inner join 테이블B 
        on 테이블A.컬럼 = 테이블B.컬럼; (on 부모테이블A.PK = 자식테이블B.FK > 99%★)
        
select 컬럼리스트 from 테이블A, 테이블B where 테이블A.컬럼 = 테이블B.컬럼;	> Oracle 전용

SELECT * FROM MEMBER INNER JOIN NOTICE ON MEMBER.ID = NOTICE.WRITER_ID;

select 
   *
from tblCustomer c
    inner join tblSales s
        on c.seq = s.cseq;

select 
    m. name as "회원",
    v.name as "비디오",
    r.rentdate as "대여날짜",
    g. price as "가격"
from tblGenre g
    inner join tblVideo v
        on g.seq = v.genre
            inner join tblRent r
                on v.seq = r.video
                    inner join tblMember m
                        on m.seq = r.member;

select 
    e.first_name || ' ' || e.last_name as "이름",
    d.department_name as "부서",
    l.city as "도시",
    c.country_name as "국가",
    r.region_name as "대륙",
    j.job_title as "직업"
from employees e
    inner join departments d
        on d.department_id = e.department_id
            inner join locations l
                on l.location_id = d.location_id
                    inner join countries c
                        on c.country_id = l.country_id
                            inner join regions r
                                on r.region_id  = c.region_id
                                    inner join jobs j
                                        on j.job_id = e.job_id;

// OUTER JOIN

- 참조키를 기준으로 일치하지 않는 행도 포함시키는 조인

- 내부 조인 결과 + 결과셋에 포함되지 못한 부모 테이블의 나머지 레코드

- 보통 outer join은 부모 테이블을 가리킨다. (보편적으로 자식 테이블은 inner join에 다 포함되기 때문)

1. LEFT : 왼쪽에 있는 테이블 중 일치하지 않는 행도 포함

2. RIGHT : 오른쪽에 있는 테이블 중 일치하지 않는 행도 포함

3. FULL : 왼쪽과 오른쪽 모두 일치하지 않는 행도 포함

select 
	컬럼리스트
from 테이블A
	(left|right|full)outer join 테이블 B
		on 테이블A.컬럼 = 테이블B.컬럼;

- LEFT

SELECT * FROM MEMBER LEFT OUTER JOIN NOTICE ON MEMBER.ID = NOTICE.WRITER_ID;

select
    * 
from tblCustomer c
    left outer join tblSales s
        on c.seq = s. cseq;

- RIGHT

SELECT * FROM MEMBER RIGHT OUTER JOIN NOTICE ON MEMBER.ID = NOTICE.WRITER_ID;

- FULL

SELECT * FROM MEMBER FULL OUTER JOIN NOTICE ON MEMBER.ID = NOTICE.WRITER_ID;

select
    w.name as "여자",
    m.name as "남자"
from tblMen m
    full outer join tblWomen w
        on m.name = w.couple;

// SELF 조인

- 자기 자신과 합치는 조인

- 1개의 테이블을 사용하는 조인

- 테이블이 스스로 자신과 관계를 맺는 경우


SELECT M.*, B.NAME BOSS_NAME FROM MEMBER M LEFT OUTER JOIN MEMBER B ON B.ID = M.BOSS_ID;

select 
    b.name as "직원명",
	a.name as "상사명"
from tblSelf a --상사
	inner join tblSelf b --직원
		on a.seq = b.super;

'데이터베이스(DB) > Oracle' 카테고리의 다른 글

[Oracle] 뷰(VIEW)  (0) 2023.02.21
[Oracle] 유니온(UNION)  (0) 2023.02.21
[Oracle] 서브 쿼리  (0) 2023.02.20
[Oracle] 순위 함수  (0) 2023.02.20
[Oracle] 집계 함수, Group by절, Having절  (0) 2023.02.20