효과적인 update 문의 0 2 2,278

by SKLEE [SQL Query] update [2016.12.13 00:11:29]


안녕하세요. 

update를 하는데 효과적인 방법이 안떠올라 문의 드립니다.

 

CREATE TABLE ZIP(
ZIP1 VARCHAR2(10)
,ZIP2 VARCHAR2(10)
,ZIP3 VARCHAR2(10)
,ZIP4 VARCHAR2(10)
,ZIP5 VARCHAR2(10)
);

CREATE TABLE MODIFY_ZIP(
OLD_ZIP VARCHAR2(10)
,NEW_ZIP VARCHAR2(10)
);


INSERT INTO ZIP VALUES( 'A' , 'S' , NULL , 'F' , 'X');
INSERT INTO ZIP VALUES( 'M' , 'D' , 'DD' , 'MM' , 'M');
INSERT INTO ZIP VALUES( NULL , 'C' , 'C' , NULL , 'C');
INSERT INTO ZIP VALUES( 'S' , 'C' , 'SS' , 'F' , 'X');
INSERT INTO ZIP VALUES( 'C' , 'S' , 'GG' , 'F' , 'G');

INSERT INTO MODIFY_ZIP VALUES( 'C' , 'CC');
INSERT INTO MODIFY_ZIP VALUES( 'S' , 'SS');
INSERT INTO MODIFY_ZIP VALUES( 'G' , 'GG');

 

zip 테이블에 있는 값들 중 modify_zip의 OLD_ZIP에 해당 값이 있으면 NEW_ZIP 값으로 바꿔야하는 문제 입니다.

한꺼번에 바꿀수 있는 방법이 안떠오르네요....

 

UPDATE

    A
SET
    ZIP1 = (CASE ZIP1 WHEN B.OLD_ZIP THEN B.NEW_ZIP ELSE ZIP1 END)
    ,ZIP2 = (CASE ZIP2 WHEN C.OLD_ZIP THEN C.NEW_ZIP ELSE ZIP2 END)
    ,ZIP3 = (CASE ZIP3 WHEN D.OLD_ZIP THEN D.NEW_ZIP ELSE ZIP3 END)
    ,ZIP4 = (CASE ZIP4 WHEN E.OLD_ZIP THEN E.NEW_ZIP ELSE ZIP4 END)
    ,ZIP5 = (CASE ZIP5 WHEN F.OLD_ZIP THEN F.NEW_ZIP ELSE ZIP5 END)
FROM
    ZIP AS A
    INNER JOIN MODIFY_ZIP AS B ON A.ZIP1 = B.OLD_ZIP
    INNER JOIN MODIFY_ZIP AS C ON A.ZIP2 = C.OLD_ZIP
    INNER JOIN MODIFY_ZIP AS D ON A.ZIP3 = D.OLD_ZIP
    INNER JOIN MODIFY_ZIP AS E ON A.ZIP4 = E.OLD_ZIP
    INNER JOIN MODIFY_ZIP AS F ON A.ZIP5 = F.OLD_ZIP;

이렇게 하면 될까 했는데...안되는군요...update에서는 with 도 안되고...

좋은 방법 있으시면 지도 부탁드립니다 ^^

 

 

by 마농 [2016.12.13 09:24:06]

오라클 업데이트 구문에는 조인 구문이 없습니다.
따라서 서브쿼리 형태로 조건을 주어야 하고, 성능에도 상당히 안좋습니다.
위 예제처럼 데이터가 몇건 안된다면 큰 문제 없지만.
데이터가 많은데 위처럼 인덱스도 없는 상황에서는 상당히 위험합니다.
인덱스 설정이 반드시 필요하구요.
머지 구문을 이용하는것도 한 방법입니다.
 

UPDATE zip a
   SET zip1 = (SELECT NVL(MIN(new_zip), a.zip1) FROM modify_zip b WHERE b.old_zip = a.zip1)
     , zip2 = (SELECT NVL(MIN(new_zip), a.zip2) FROM modify_zip b WHERE b.old_zip = a.zip2)
     , zip3 = (SELECT NVL(MIN(new_zip), a.zip3) FROM modify_zip b WHERE b.old_zip = a.zip3)
     , zip4 = (SELECT NVL(MIN(new_zip), a.zip4) FROM modify_zip b WHERE b.old_zip = a.zip4)
     , zip5 = (SELECT NVL(MIN(new_zip), a.zip5) FROM modify_zip b WHERE b.old_zip = a.zip5)
 WHERE EXISTS (SELECT 1
                 FROM modify_zip b
                WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5)
               )
;
UPDATE zip a
   SET (zip1, zip2, zip3, zip4, zip5)
     = (SELECT MIN(DECODE(a.zip1, b.old_zip, b.new_zip, a.zip1)) zip1
             , MIN(DECODE(a.zip2, b.old_zip, b.new_zip, a.zip2)) zip2
             , MIN(DECODE(a.zip3, b.old_zip, b.new_zip, a.zip3)) zip3
             , MIN(DECODE(a.zip4, b.old_zip, b.new_zip, a.zip4)) zip4
             , MIN(DECODE(a.zip5, b.old_zip, b.new_zip, a.zip5)) zip5
          FROM modify_zip b
         WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5)
        )
 WHERE EXISTS (SELECT 1
                 FROM modify_zip b
                WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5)
               )
;
MERGE INTO zip a
USING
(
SELECT a.ROWID rid
     , MIN(DECODE(a.zip1, b.old_zip, b.new_zip, a.zip1)) zip1
     , MIN(DECODE(a.zip2, b.old_zip, b.new_zip, a.zip2)) zip2
     , MIN(DECODE(a.zip3, b.old_zip, b.new_zip, a.zip3)) zip3
     , MIN(DECODE(a.zip4, b.old_zip, b.new_zip, a.zip4)) zip4
     , MIN(DECODE(a.zip5, b.old_zip, b.new_zip, a.zip5)) zip5
  FROM zip a
     , modify_zip b
 WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5)
 GROUP BY a.ROWID
) b
ON (a.ROWID = b.rid)
WHEN MATCHED THEN
UPDATE SET a.zip1 = b.zip1
         , a.zip2 = b.zip2
         , a.zip3 = b.zip3
         , a.zip4 = b.zip4
         , a.zip5 = b.zip5
;

 


by 손님 [2016.12.13 18:18:38]
마농님 다양한방법과 조언 감사드립니다~~
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입