본문 바로가기

Oracle/SQL

SQL [DML문] MERGE 데이터 삽입,수정,삭제 한번에

1. 현업에서는 업데이트 문장을 빠르게 수행 하고싶을때, 튜닝의 용도로 많이 사용합니다.

2. INSERT, UPDATE, DELETE 를 한번에 수행하는 SQL 이고,

3. 주로 대용량 데이터를 한번에 UPDATE 하여 SQL 성능을 개선하기 위해서 사용됩니다.

예제 : emp 와dept 조인하여 사원이름, 부서위치 출력

select e.ename, d.loc
from emp e, dept d
where e.deptno = d.deptno;

예제 emp 와 dept 를 조인하지 않고 그냥 emp 테이블에서 부서위치에 대한 데이터도 보기위해 emp 테이블에 loc 컬럼을 추가

alter table emp
add loc varchar2(10);

예제 : loc 에 각각 update 를 해야하는데 update 문 말고 merge 문을 이용하여 loc컬럼의 값을 갱신

merge into emp
using dept 
on (e.deptno = d.detpno)
when matched then 
set e.loc = d.loc ;

1. emp e 테이블을 merge 하는데

2. dept d 테이블을 사용하여 merge 해라

3. 이때 두개의 테이블의 연결 고리는 deptno 이다.

4. on 절에 나온 emp 테이블의 deptno 가 dept 테이블에 매칭 한다면

5. e.loc 를 d.loc 로 업데이트 (갱신)해라.

별칭 !!!!!! 사용

문제 402 번 emp 테이블에 dname 컬럼을 추가

alter table emp
add dname varchar2(10);

문제 403 emp 에 추가한 dname 컬럼값을 dept 테이블의 dname 으로 갱신하시오 (자기자신의 부서명으로 값을 갱신)

merge into emp e
using dept d
on ( e.deptno = d.deptno)
when matched then
update set d.dname = e.dname ;

 

→ 머지문 사용


update emp e
set loc = ( select d.loc
            from dept d
            where e.deptno = d.deptno)
           ;

→ 서브쿼리문 사용

메인쿼리 먼저 수행된다.

그렇게 되면 emp 의 deptno 의 수를 가지고 하나하나 서브쿼리로 가져가서 대입하기 때문에

emp 테이블의 데이터가 많을 수록 성능이 떨어지게된다.

emp 테이블에 14 건이 있으니까 14 번 수행하게 된다. 만약 emp 테이블이 1억건이 있다면 1억건 update 하게 된다.


문제 404 emp14 에 telecom_price 테이블 생성

alter table emp14
add telecom_price number(10) ;

문제 405 update 문으로 작성할것 (악성 sql)telecom_service 의 pirce 를 emp14 에 telecom_price 로 갱신해라

update up14 e
set e.price = (select price 
               from telecom_servie t 
               where e.telecom = t.telecom);

문제 406 merge 문으로 작성할 것 (튜닝후 sql)

merge into emp14 e
using telecom_service t
on (e.telecom = t.telecom)
when matched then 
update set e.price = t.price

문제 407 점심시간 문제

alter table emp
add grade number(10);

merge into emp e
using salgarde s 
on (e.sal between losal and hisal )
when matched then 
update set e.grade = s.grade ;

MERGE 문을 새롭게 쓰는 방법

문제 부서번호별 인원수를 출력하시오 ~ 

select deptno, count(*)
from emp
group by deptno ;

문제  부서테이블에 cnt 라는 컬럼을 숫자형으로 추가

alter table dept
add cnt number(10);

문제 추가한 cnt 컬럼에 문제408에 구한 count 인원수를 cnt 에 갱신하시오


using 에 emp 를 온전히 사용할 수가 없는게 count 는 emp 테이블에서 데이터 분석으로써 추출한 새로운 값이라 기존 컬럼에 없기 때문이다. 그래서 using 절에 쿼리문을 가져다가 썼다. 

merge into dept d
using (select deptno , count(*)cnt
       from emp 
       group by deptno)v
on (e.deptno = v.deptno)
when matched then 
update set d.cnt = v.cnt

view 를 써서  merge 문 쓰는 방법으로 하면 조금 더 간단하게 할 수 있다. 

view 생성문 

create view emp_cnt_view
as
select deptno, count(*) cnt 
from emp
group by deptno ;

문제 부서번호별 총월급을 구하기 

select deptno, sum(sal)
from emp
group by deptno;

문제 dept 테이블에 sumsal 컬럼을 number 데이터 형식으로 추가 

alter table dept 
add sumsal number(10);

문제 413 지금 추가한 sunsal컬럼에 데이터를 해당 부서번호의 토탈월급으로 값을 갱신하시오 (merge 문)

mgerge into dept d
using (select deptno, sum(sal) sumsal
      from emp
      group by deptno) v
on (d.deptno = v.deptno)
when matched then
update set d.sumsal = v.sumsal ;

-> 꼭 주의해아할 사항은 using 절에 서브쿼리를 작성할 때 꼭 데이터 분석함수를 넣은 부분엔 별칭을 써 주어야하고 서브쿼리 자체에도 테이블 별칭을 주어야 한다는 점이다!