ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL BOOSTER - MERGE
    DataBase/SQL 2024. 6. 23. 16:10

     

    1. MERGE란?

     

    데이터 존재 여부에 따라 데이터를 INSERT하거나 UPDATE하는 경우가 많다. 이때 유용하게 사용할 수 있는 것이 MERGE이다. 

     

    MERGE는 한 문장으로 INSERT와 UPDATE를 동시에 처리할 수 있다. 한 건의 데이터가 동시에 INSERT와 UPDATE되는 것은 아니다. 한 건의 데이터는 INSERT와 UPDATE 중 하나만 수행된다.

    MERGE 대상이 이미 존재하면 UPDATE, 대상이 존재하지 않으면 INSERT를 수행하는 방식이다.

     

    예를 들어 고객 ID와 고객 정보를 외부에서 입력 변수로 받는다. 이때 같은 고객 ID가 이미 있으면, 고객 정보를 업데이트하고, 같은고객 ID가 없으면 신규 고객으로 등록한다. 

     

    MERGE INTO M_CUS_CUD T1
    USING(
    
       SELECT 'CUS_0090' CUS_ID
              ,'NAME_0090' CUS_NM
              ,'A' CUS_GD
       FROM DUAL
       )T2
       ON (T1.CUS_ID = T2.CUS_ID)
    WHEN MATCHED THEN UPDATE SET T1.CUS_NM = T2.CUS_NM, T1.CUS_GD = T2.CUS_GD
    WHEN NOT MATHCES THEN INSERT (T1.CUS_ID, T1.CUS_NM, T1.CUS_GD) VALUES(T2.CUS_ID,T2.CUS_NM,T2.CUS_GD);
    
    COMMIT;
    1. MERGE 대상: MERGE INTO 뒤에 작성
    2. 비교대상 : USING절 뒤에 정의 - 인라인 뷰 혹은 실제 테이블 사용 
    3. 비교조건 ON : 비교 조건 결과에 따라 UPDATE나 INSERT를 처리할 수 있다. 
      1. MATCHED THEN : 비교 대상 데이터가 MERGE 대상에 이미 있으면 UPDATE
      2. NOT MATCHED THEN : 비교 대상 데이터가 MERGE 대상에 없으면, INSERT

    2. MERGE를 사용한  UPDATE

     

    MERGE 문장에서 WHEN MATCHED THEN 절을 이용해 UPDATE를 처리하고, WHEN NOT MATCHED THEN 절을 이용해 INSERT를 한다. 

    MERGE 문장에서 WHEN MATCHED THEN 절만 사용하면, 해당 MERGE문은 UPDATE만 처리한다. 

     

     

    SQL BOOSTER

     

    INSERT INTO S_CUS_YM (BAS_YM,CUS_ID,ITM_TP, ORD_QTY,ORD_AMT)
    SELECT '201702' BAS_YM, T1.CUS_ID, T2.BAS_CD TIM_TP, NULL ORD_QTY, NULL ORD_AMT
    FROM M_CUS T1, C.BAS_CD T2
    WHERE T2.BAS_CD_DV = 'ITM_TP'
    AND T2.LNG_CD = 'KO'
    
    COMMIT;

     

    해당 테이블에 위 SQL을 실행하면, 17년 2월의 고객ID, 아이템유형별 데이터가 입력된다. 

    ORD_QTY와 ORD_AMT는 모두 NULL값으로 입력되어 있다. ORD_QTY와 ORD_AMT를 UPDAE하려면 T_ORD_DET를 이용해야한다. 따라서 UPDATE시 다음과 같이 해야한다.

     

    UPDATE S_CUS_YM T1
    SET T1.ORD_QTY = (SELECT SUM(B.ORD_QTY)
                      FROM T.ORD A, T_ORD_DET B, M_ITM C
                      WHERE A.ORD_SEQ = B.ORD_SEQ
                      AND C.ITM_ID = B.ITM_ID
                      AND C.ITM_TP = T1.ITM_TP
                      AND A.CUS_ID = T1.CUS_ID
                      )
                      //.. 생략

     

    ORD_QTY와 ORD_AMT를 UPDATE를 하기 위해 서브쿼리를 두번 사용해야한다. 이는 성능에 좋지 못하다.

    위 SQL은 아래와 같은 MERGE를 사용해 UPDATE할 수 있다. 

     

    MERGE INTO S_CUS_YM T1
    
    USING( SELECT A.CUS_ID, C.ITM_TP, SUM(B.ORD_QTY) ORD_QTY, SUM(B.UNT_PRC * B.ORD_QTY) ORD_AMT
           FROM T_ORD A, T_ORD_DET B, M_ITM C
           WHERE A.ORD_SEQ = B.ORD_SEQ
           AND C.ITM_ID = B.ITM_ID
           AND A.ORD_DT >= TO_DATE('201702'||'01','YYYYMMDD')
           AND A.ORD_DT < ADD_MONTHS(TO_DAE('201702'||'01','YYYYMMDD'),1)
           GROUP BY A.CUS_ID, C.ITM_TP) T2
           
           ON(T1.BAS_YM = '201702'
              AND T1.CUS_ID = T2.CUS_ID
              AND T1.ITM_TP = T2.ITM_TP)
    WHEN MATCHED THEN UPDATE SET T1.ORD_QTY = T2.ORD.QTY, T1.ORD_AMT = T2.ORD_AMT;
    
    COMMIT;

     

    • UPDATE와 MERGE는 다르다. UPDATE는 S_CUS_YM의 '201702' 데이터가 모두 UPDATE된다. 
    • MERGE의 경우 주문 실적이 발생한 데이터만 변경 한다. 
    • 만약 주문 실적이 없는 데이터는 NULL이 아니라 0으로 처리해야한다면, MERGE문을 변경할 필요가 있다. 

    참고자료 

    https://www.yes24.com/Product/Goods/82818767

     

    SQL BOOSTER - 예스24

    SQL BOOSTER는 프로젝트 성공을 위한 SQL 필독서다. 이 책은 마치 프로젝트를 진행하는 순서처럼 구성되어 있다. 프로젝트 투입을 위해 필요한 SQL 기술을 설명하고, 성능 테스트를 위해 필요한 기술

    www.yes24.com

     

    'DataBase > SQL' 카테고리의 다른 글

    SQL BOOSTER - HASH JOIN과 성능  (0) 2024.06.24
    SQL BOOSTER - MERGE 조인과 성능  (0) 2024.06.24
    SQL BOOSTER - 서브쿼리 (WHERE)  (0) 2024.06.23
    SQL BOOSTER - 서브쿼리 (SELECT)  (0) 2024.06.23
    SQL BOOSTER - OUTER JOIN  (0) 2024.06.20
Designed by Tistory.