본문 바로가기

Oracle

다른 테이블을 참조하여 UPDATE 하는 방법

다른 테이블의 SELECT 한 결과물을 참조하여 현재 테이블을 UPDATE 해야 하는 상황이 있습니다.

Oracle, MS-SQL, Maria DB, Mysql DBMS마다 다른 문법을 지원하므로 방법도 각자 다릅니다.

저는 Oracle을 사용 중인데 다른 DBMS 보다 조금 문법이 어려운 것 같네요 이 방법에 한해서는요 ㅎㅎ

table master, table user 두 개의 테이블이 있다고 가정하겠습니다.

master 테이블의 Status을 user 테이블의 Status의 값을 참조하여 변경하는 쿼리를 작성해보겠습니다.

MS-SQL

UPDATE
    master
SET
    master.status = cust.status
FROM
    master m
INNER JOIN
    cust c
ON 
    m.id = c.id;

MySQL and MariaDB

UPDATE
    master m,
    cust c
SET
    m.status = c.status
WHERE
    m.id = c.id;

Oracle

단순 업데이트만 사용하는 방법

EXISTS를 사용하지 않으면 첫 번째 서브 쿼리의 id 키 값이 매칭 되지 않는 값들은 master의 status 값이 null로 변경됩니다. 

UPDATE master m
SET    m.status = (select c.status
                  from cust c 
                  where m.id = c.id)
WHERE EXISTS (select 1
              from cust c
              where m.id = c.id)

merge into를 구문을 사용하는 방법

MERGE INTO master m
USING cust c
ON (m.id = c.id)
WHEN MATCHED THEN UPDATE SET m.status = c.status;

Oracle 실습

master table
cust table

이 쿼리를 실행해보겠습니다.

UPDATE master m
SET    m.status = (select c.status
                  from cust c 
                  where m.id = c.id)
WHERE EXISTS (select 1
              from cust c
              where m.id = c.id)

우리가 기대하는 결과는 master 테이블의 test1, test3, test5의 status값이 FALSE로 변환되는 결과입니다.

update 결과

올바르게 변환됩니다!

그런데 만약 아래와 같이 EXIST 구문을 빼면 어떻게 될까요?

UPDATE master m
SET    m.status = (select c.status
                  from cust c 
                  where m.id = c.id)

update 결과

test2와 test4는 id 키 값이 매칭되는 것이 없으므로 status의 값이 null로 변경됩니다. 기본적으로 update 구문에서 where 조건을 설정하지 않으면 전체 테이블을 update하게 되어서 나타나는 결과입니다.

merger into 쿼리의 결과 역시 제대로 업데이트 되는 것을 볼 수 있습니다!

MERGE INTO master m
USING cust c
ON (m.id = c.id)
WHEN MATCHED THEN UPDATE SET m.status = c.status;

merge into 결과