(→장점 요약) |
편집 요약 없음 |
||
(같은 사용자의 중간 판 2개는 보이지 않습니다) | |||
11번째 줄: | 11번째 줄: | ||
# A 테이블에 B 테이블 데이터를 넣고 싶은데, 이미 있는 데이터는 UPDATE 하고 없는 데이터는 INSERT 해야 할 때 | # A 테이블에 B 테이블 데이터를 넣고 싶은데, 이미 있는 데이터는 UPDATE 하고 없는 데이터는 INSERT 해야 할 때 | ||
# 데이터 동기화, 이력 테이블 관리, 배치 업데이트 등에서 자주 사용 | # 데이터 동기화, 이력 테이블 관리, 배치 업데이트 등에서 자주 사용 | ||
=== 기본 문법 === | === 기본 문법 === | ||
25번째 줄: | 25번째 줄: | ||
</source> | </source> | ||
=== 예제 === | === 예제 === | ||
35번째 줄: | 32번째 줄: | ||
대상 테이블: target_employees | 대상 테이블: target_employees | ||
{| class="wikitable sortable" style="width:80%; margin:auto;" | |||
1 Alice | ! style="text-align:center; background:#f8f9fa;" | ID | ||
2 Bob | ! style="text-align:left; background:#f8f9fa;" | Employee | ||
! style="text-align:right; background:#f8f9fa;" | Monthly Salary | |||
|- | |||
| style="text-align:center;" | 1 || style="text-align:left;" | Alice || style="text-align:right;" | $3,000 | |||
|- | |||
| style="text-align:center;" | 2 || style="text-align:left;" | Bob || style="text-align:right;" | $3,200 | |||
|} | |||
원본 테이블: source_employees | 원본 테이블: source_employees | ||
{| class="wikitable sortable" style="width:80%; margin:auto;" | |||
2 Bob | ! style="text-align:center; background:#f2f2f2;" | Employee ID | ||
3 Carol | ! style="text-align:left; background:#f2f2f2;" | Name | ||
! style="text-align:right; background:#f2f2f2;" | Salary (USD) | |||
|- | |||
| style="text-align:center;" | 2 || style="text-align:left;" | Bob || style="text-align:right;" | 3,500 | |||
|- | |||
| style="text-align:center;" | 3 || style="text-align:left;" | Carol || style="text-align:right;" | 2,800 | |||
|} | |||
{| class="wikitable" style="width: 80%; text-align: center;" | {| class="wikitable" style="width: 80%; text-align: center;" | ||
70번째 줄: | 79번째 줄: | ||
=== MERGE 쿼리 === | === MERGE 쿼리 === | ||
89번째 줄: | 97번째 줄: | ||
실행 결과 | 실행 결과 | ||
emp_id name salary | {| class="wikitable" style="width:80%;" | ||
1 Alice | ! emp_id !! name !! salary | ||
2 Bob | |- | ||
3 Carol | | 1 || Alice || $3,000 | ||
|- | |||
| 2 || Bob || $3,500 | |||
|- | |||
| 3 || Carol || $2,800 | |||
|} | |||
=== 조건 추가 (WHERE 사용) === | === 조건 추가 (WHERE 사용) === | ||
111번째 줄: | 120번째 줄: | ||
=== 장점 요약 === | === 장점 요약 === | ||
2025년 5월 22일 (목) 21:37 기준 최신판
MERGE 구문
- MERGE는 특히 ETL 작업, 데이터 동기화, UPSERT 작업에서 많이 사용돼요.
menu_book MERGE란?
- (영문): The MERGE statement allows you to conditionally insert or update data in a target table based on the results of a join with a source table.
- (한글): MERGE는 하나의 SQL 문으로, 대상 테이블에 대해 조건에 따라 INSERT(삽입) 또는 **UPDATE(갱신)**를 할 수 있는 문법입니다. 흔히 “UPSERT” (update + insert)라고 부르기도 해요.
언제 쓰나요?
- A 테이블에 B 테이블 데이터를 넣고 싶은데, 이미 있는 데이터는 UPDATE 하고 없는 데이터는 INSERT 해야 할 때
- 데이터 동기화, 이력 테이블 관리, 배치 업데이트 등에서 자주 사용
기본 문법
MERGE INTO 대상테이블 t USING 원본테이블 s ON (t.기준컬럼 = s.기준컬럼) WHEN MATCHED THEN UPDATE SET t.컬럼1 = s.컬럼1, ... WHEN NOT MATCHED THEN INSERT (컬럼1, 컬럼2, ...) VALUES (s.컬럼1, s.컬럼2, ...);
예제
예제 테이블
대상 테이블: target_employees
ID | Employee | Monthly Salary |
---|---|---|
1 | Alice | $3,000 |
2 | Bob | $3,200 |
원본 테이블: source_employees
Employee ID | Name | Salary (USD) |
---|---|---|
2 | Bob | 3,500 |
3 | Carol | 2,800 |
emp_id | name | salary |
---|---|---|
1 | Alice | 3000 |
2 | Bob | 3200 |
emp_id | name | salary |
---|---|---|
2 | Bob | 3500 |
3 | Carol | 2800 |
MERGE 쿼리
MERGE INTO target_employees t USING source_employees s ON (t.emp_id = s.emp_id) WHEN MATCHED THEN UPDATE SET t.salary = s.salary WHEN NOT MATCHED THEN INSERT (emp_id, name, salary) VALUES (s.emp_id, s.name, s.salary);
실행 결과
emp_id | name | salary |
---|---|---|
1 | Alice | $3,000 |
2 | Bob | $3,500 |
3 | Carol | $2,800 |
조건 추가 (WHERE 사용)
WHEN MATCHED THEN UPDATE SET t.salary = s.salary WHERE s.salary > t.salary -- 조건 만족할 때만 갱신 WHEN NOT MATCHED THEN INSERT (emp_id, name, salary) VALUES (s.emp_id, s.name, s.salary) WHERE s.salary >= 2500; -- 조건 만족할 때만 삽입
장점 요약
장점 | 설명 |
---|---|
한 문장으로 처리 | MERGE INTO target t<br> USING source s<br> ON (t.id = s.id)<br> WHEN MATCHED THEN UPDATE SET...<br> WHEN NOT MATCHED THEN INSERT... → 단일 쿼리로 INSERT/UPDATE 동시 처리 가능 |
조건부 UPSERT | WHEN MATCHED AND s.status='active' THEN UPDATE...<br> WHEN MATCHED AND s.status='expired' THEN DELETE... → 조건에 따라 UPDATE/DELETE/INSERT 액션 분기 처리 |
성능 최적화 가능 | - 테이블 풀 스캔 방지 |
주의사항
- MERGE는 DELETE도 처리 가능하지만, 사용 시 주의 필요
- 트리거나 제약조건이 있는 테이블에서는 충돌 가능성 있음
- 대상 테이블과 원본 테이블은 충분히 식별 가능한 기준 컬럼으로 JOIN 해야 함