관리 메뉴

오버플로

[Oracle] union / join / driving table 본문

Oracle

[Oracle] union / join / driving table

NACO 2021. 9. 26. 19:10

 1. union 

- 여러 개의 테이블의 조회 결과를 아래로 붙여서 조회하는 쿼리문

- 컬럼의 이름은 상관없음. (단, 조회되는 인라인뷰의 컬럼명은 첫 번째 쿼리문의 컬럼명이 나옴)

1) 조건

 ① 위 테이블의 컬럼 데이터형과 아래에 연결되는 테이블의 컬럼의 데이터형이 일치할 것

 ② 위 테이블의 컬럼 개수와 아래 테이블의 컬럼의 개수가 일치할 것
    > 테이블이 가지고 있는 컬럼 개수가 아니라 조회할 때의 컬럼 개수

2) 종류

- union : 중복 레코드가 출력되지 않음

- union all : 중복 레코드가 출력됨

3) 문법)

         select 컬럼명 ,,, from 테이블명 [where~group by ~ ,,,,]

         union [all]

         select 컬럼명 ,,, from 테이블명 [where~group by ~ ,,,,]

         union [all]

         select 컬럼명 ,,, from 테이블명 where~group by ~ ,,,,]

         .... 

 

** union은 컬럼을 조회하지 않고 고정값으로 조회할 수 있음

 - 원래 데이터가 있음에도 지정한 고정값으로 조회 결과가 합쳐짐

 - 고정값 지정 시 컬럼의 데이터형과 같은 형식으로 기입해야 함!

 - 없는 컬럼도 고정값으로 추가하여 조회할 수 있음

 

 

 

  2. join 

- 서로 다른 테이블을 합쳐서(옆으로 붙여서) 조회할 때 

- 정규화(normalization)가 진행되면 테이블이 분리되어 데이터가 저장됨

  => 쪼개진 데이터를 붙여서 가져오기 위해 join 수행

- oracle에서는 Oracle join문법ANSI join 문법을 제공함

=> ANSI(American National Strandards Institute) query는 모든 DBMS에서 사용가능(좀 길다)

- 종류 : inner join, outer join, self join, cross join(=full outer join)이 존재

- 주의

   ① 조인 조건을 잘못 설정하면 cartesian product(카티션 프로덕트)가 발생 (=데카르트 곱)

         => 모든 레코드가 곱해져서 결과로 생성됨 (이렇게 조회된 레코드는 난장판~)

   ② 조인의 키가 되는 driving table을 주의하여 선정 (속도의 차)

 

** driving table

- 조인 시 key가 되는 table

  (조인 조건 작성할때, ‘비교테이블 = 기준테이블’ 이렇게 작성 / 기준 table이 driving 테이블)

- 선정기준 : 부모(PK)-자식(FK) 관계라면 부모가 driving table

                    : 레코드의 건수가 적은 테이블

                    : 레코드의 수가 비슷하다면, 레코드의 다양성이 적은 테이블

- driving table을 잘 선정하면 검색횟수가 줄어서 속도가 향상됨!!

 

** equi join(등가조인) : 값이 같은 걸(=) 조인 조건에 넣는 것 (emp.dept no = dept.deptno)

    non-equi join : ‘=’ 연산자 이외의 비교 연산자를 사용하는 것

 

 

1) inner join

- 양쪽 테이블에 같은 컬럼 값이 존재하는 레코드만 조회

- 모든 레코드를 조회할 수 없음

- 문법)

ANSI ORACLE
select          컬럼명, 테이블명.컬럼명, alias.컬럼명
from            테이블명 alias
inner join  조인할 테이블 명 alias
on                조인조건 (alias 사용)

where         검색조건
select    컬럼명, 테이블명.컬럼명, alias.컬럼명
from      테이블명 alias, 조인할 테이블명 alias,,,
where    조인조건 and 검색조건

* on은 보통 key를 비교하게 됨 (PK나 FK)

* from의 테이블과 join 테이블의 순서는 상관없음 (어차피 같은 값 찾아서 조회하기 때문!)

 

 

2) outer join

- 한쪽 테이블에만 레코드가 존재하더라도 검색 가능

- outer join 종류 : left, right, full

   > 레코드가 존재하는 테이블을 선정하는 것 (잘못 선정하면 inner join과 같아짐)

   > 레코드의 구성을 알 때 : left, right / 레코드의 구성을 모를 때 : full

   > full outer를 사용하면 속도가 엄청 느려지고 순서가 뒤섞여서 잘 안씀 (oracle에서 full outer join은 지원 안 함)

- 문법)

* 주의) ANSI와 Oracle은 레코드가 있는쪽/없는쪽 사용이 다름

ANSI ORACLE
select                       컬럼명, 테이블명.컬럼명, alias.컬럼명
from                         테이블명 alias
종류 [outer] join  조인할 테이블 명 alias
on                             조인조건 (alias 사용)

where                     검색조건
select    컬럼명, 테이블명.컬럼명, alias.컬럼명
from      테이블명 alias, 조인할 테이블명 alias,,,
where   조인조건 and 검색조건
               -- 조인조건 : 레코드가 없는 쪽에 (+)
              

* ANSI) 조인할 테이블과 조회할 컬럼명에는 key가 되는 테이블을 사용해야 함

    > 부모 테이블과 같이 모든 종류의 레코드를 가지고 있는 테이블을 사용!

    > left outer join일 경우, from에 키가 되는 테이블

       right outer join일 경우, from 다음에 오는 조인 테이블에 키가 되는 테이블 기재

* oracle outer join) 조인 조건에 (+) 기호를 레코드가 없는 쪽 컬럼에 기술

    > driving table을 뒤에 배치하니까 웬만해서는 alias.컬럼명(+) = alias.컬럼명 (반대도 당연 가능)

    >> 단, (+)를 양쪽 모두에 붙일 수 없음 (oracle은 full outer join 지원하지 않음)

 

 

3) self join

- 하나의 테이블을 join하는 것 

- 테이블에 alias를 필수적으로 부여하고(테이블 식별), 검색목적과 조건목적으로 테이블을 구분하여 사용

> 조회목적 (조회하는 컬럼과 조인 조건에만 등장) / 조건목적 (조인조건과 검색조건에만 등장)

- 조인 조건이 다른 것을 가져오는 non-equi join을 많이 사용함 ('='인 equi join을 사용하면 쓰레기값이 나오기도 함)

- ANSI는 없고 Oracle query만 존재함

ORACLE
select     a.컬럼명 ,,,   -- 검색목적 테이블의 alias를 사용
from       테이블명 alias a (검색목적), 테이블명 alias b (비교/조건목적) ,,,
where    조인조건 and 검색조건   
                 -- 조인 조건은 보통 non-equi

                 -- 검색 조건은 비교목적 테이블의 alias를 사용

 

 


# 오늘의 코딩 #

- union과 join을 사용해보잣

 

#union

--emp : 본사, cp_emp4 : 지사

--------------------union : 중복 레코드가 출력되지 않음--------------------
--본사와 지사 사원을 조회 (단, 중복레코드를 조회하지 않아야 함)
select empno, ename, sal, hiredate, deptno
from emp
union
select empno, ename,  sal, hiredate, deptno
from cp_emp4;

#출력 결과#

-> 본사와 지사의 중복 값을 제외한 데이터들이 출력됨!

-> union all을 사용하면 중복 레코드도 출력된당

 


#join

- outer join을 ANSI와 Oracle 문법으로 사용해보장

----------------outer join-----------------
--제조사가 '현대'인 모든 차량의 모델명, 연식, 가격, 옵션을 조회해보자
--주의사항) 조회컬럼에 키가 되는 컬럼을 사용해야 결과를 얻을 수 있음

--<ANSI>
select           cma.maker, cma. model, cmo.car_year, cmo.price, cmo.car_option
from             car_model cmo
right outer join car_maker cma
on               cmo.model = cma.model
where            cma.maker = '현대';

--<Oracle>
select cma.maker, cma. model, cmo.car_year, cmo.price, cmo.car_option
from   car_maker cma, car_model cmo
where  (cmo.model(+) = cma.model) and cma.maker = '현대';

#출력 결과#

-> ANSI보단 Oracle 문법이 사용하기엔 간단하다

-> outer join이라 한쪽 테이블에만 값이 존재하더라도 모든 값이 나오는 것을 확인!

 

'Oracle' 카테고리의 다른 글

[Oracle] alter  (0) 2021.09.29
[Oracle] 제약사항 (Constraint)  (0) 2021.09.28
[Oracle] subquery / Scalar subquery / inline view  (0) 2021.09.24
[Oracle] function(함수)  (0) 2021.09.20
[Oracle] select - where / group by ~ having / order by  (0) 2021.09.19
Comments