NVL, NVL2, COALESCE의 차이 – NULL 처리 함수 완전 정복

Posted by heoncode
2025. 7. 31. 12:59 오라클 실무 쿼리 튜닝
반응형

SQL을 작성하다 보면 NULL 값을 다른 값으로 대체해야 할 일이 자주 발생합니다. 이때 사용하는 대표적인 함수로 NVL, NVL2, COALESCE가 있으며, 모두 오라클에서 널 처리에 사용됩니다. 이름은 비슷하지만 동작 방식과 활용도에는 차이가 있기 때문에 정확히 구분하고 사용하는 것이 중요합니다.

이 글에서는 세 함수의 문법, 차이점, 예제, 실무 팁까지 함께 정리합니다.

1. NVL – 기본적인 NULL 대체

NVL은 가장 단순한 널 처리 함수로, NULL이면 지정한 값으로 대체하고, NULL이 아니면 원래 값을 그대로 반환합니다.

NVL(표현식, 대체값)

예시:

SELECT NVL(NULL, 'N/A') FROM DUAL; -- 결과: 'N/A'
SELECT NVL('ABC', 'N/A') FROM DUAL; -- 결과: 'ABC'

주의할 점은 데이터 타입이 일치해야 한다는 점입니다. 숫자와 문자열을 섞으면 오류가 납니다.

SELECT NVL(100, '없음') FROM DUAL; -- 오류 발생

2. NVL2 – NULL 여부에 따라 두 값을 선택

NVL2NULL이냐 아니냐에 따라 두 개의 다른 값을 선택할 수 있습니다.

NVL2(표현식, NOT_NULL일 때 반환값, NULL일 때 반환값)

예시:

SELECT NVL2(NULL, 'Y', 'N') FROM DUAL; -- 결과: 'N'
SELECT NVL2('데이터', 'Y', 'N') FROM DUAL; -- 결과: 'Y'

즉, IF 문으로 치면 다음과 같은 형태입니다.

IF (표현식 IS NOT NULL) THEN A ELSE B

단순 대체가 아니라 두 갈래 조건 분기가 필요할 때 유용합니다.

3. COALESCE – 첫 번째 NOT NULL 값을 반환

COALESCE는 인수들을 왼쪽부터 검사하여 첫 번째로 NULL이 아닌 값을 반환합니다. 인수는 2개 이상 받을 수 있고, 여러 후보 중 유효한 값을 찾을 때 매우 유용합니다.

COALESCE(표현식1, 표현식2, ..., 표현식N)

예시:

SELECT COALESCE(NULL, NULL, '대체', '기본') FROM DUAL; -- 결과: '대체'

NVL과 다르게 여러 후보를 순차적으로 검사할 수 있고, 타입 자동 변환도 좀 더 유연합니다.

세 함수 비교 정리

항목 NVL NVL2 COALESCE
사용 목적 NULL이면 대체 NULL 여부로 분기 여러 후보 중 첫 NOT NULL
인수 개수 2개 3개 2개 이상
가독성 간단 조건 분기에 적합 유연한 NULL 처리
데이터 타입 동일 타입 요구 자유 자동 변환 가능
표준 SQL 여부 오라클 전용 오라클 전용 SQL 표준 지원

실무 활용 팁

  • 단순한 기본값 설정: NVL
  • NULL 여부에 따라 값 분기: NVL2
  • 여러 후보 중 유효값 찾기: COALESCE
  • 이식성과 SQL 표준을 고려한다면 COALESCE를 우선 고려하는 것이 좋습니다.

예: 고객 이름이 NULL이면 닉네임, 닉네임도 없으면 '비회원'을 보여주고 싶을 때

SELECT COALESCE(NAME, NICKNAME, '비회원') FROM USER_TABLE;

마무리

NVL, NVL2, COALESCE는 모두 NULL 값을 처리하는 데 유용하지만, 목적과 상황에 따라 적절한 함수를 선택해야 합니다. 단순히 외워서 사용하는 것이 아니라, 동작 방식과 차이를 이해하고 쿼리 목적에 맞게 활용하는 것이 중요합니다.

#NULL처리 #NVL함수 #COALESCE #오라클SQL #SQL기초 #오라클쿼리 #NVL2사용법 #NULL함수비교

반응형

DECODE vs CASE – 오라클에서 조건 분기를 처리하는 두 가지 방법 비교

Posted by heoncode
2025. 7. 28. 17:23 오라클 실무 쿼리 튜닝
반응형

오라클에서 조건 분기를 처리할 때 흔히 사용하는 문법으로 DECODECASE가 있습니다. 둘 다 특정 값에 따라 다른 결과를 반환하는 용도로 사용되지만, 기능과 표현력 면에서는 뚜렷한 차이가 있습니다. 이 글에서는 두 문법의 구조와 차이점을 예제를 통해 비교하고, 실무에서 어떤 상황에 어떤 문법을 선택하는 것이 좋은지 정리합니다.

DECODE 문법과 특징

DECODE는 IF-ELSE 형태로 특정 컬럼의 값을 비교해 결과를 반환합니다. 단순한 조건 분기에서 간결하게 사용할 수 있습니다.

DECODE(표현식, 조건1, 결과1, 조건2, 결과2, ..., 기본값)

예를 들어 고객 등급을 숫자 코드로 표시하는 경우 다음과 같이 사용할 수 있습니다.

SELECT
    CUST_ID,
    DECODE(GRADE, 'A', '우수', 'B', '일반', 'C', '관망', '기타') AS GRADE_DESC
FROM CUSTOMER;

CASE 문법과 특징

CASE는 SQL 표준 문법이며, 다양한 조건을 조합해 표현할 수 있는 유연한 구조입니다.

CASE
    WHEN 조건1 THEN 결과1
    WHEN 조건2 THEN 결과2
    ...
    ELSE 기본값
END

위 DECODE 예제를 CASE로 바꾸면 다음과 같습니다.

SELECT
    CUST_ID,
    CASE
        WHEN GRADE = 'A' THEN '우수'
        WHEN GRADE = 'B' THEN '일반'
        WHEN GRADE = 'C' THEN '관망'
        ELSE '기타'
    END AS GRADE_DESC
FROM CUSTOMER;

주요 차이점 비교

항목 DECODE CASE
지원 범위 오라클 전용 SQL 표준
비교 방식 값 = 값 복잡한 조건 가능
표현식 위치 표현식 기반 조건 전체 자유롭게 작성
NULL 처리 NULL = NULL 비교 불가 IS NULL 등 명시 가능
가독성 간결함 구조적 표현 가능
중첩 표현 가능하나 가독성 저하 구조적으로 중첩 가능

실무 사용 팁

  • 간단한 값 비교: DECODE가 짧고 빠르게 사용할 수 있습니다.
  • 다양한 조건 포함: CASE가 유리합니다. BETWEEN, IS NULL, LIKE 등 다양한 조건을 쓸 수 있기 때문입니다.
  • 표준 SQL 고려: 이식성과 유지보수를 고려한다면 CASE를 기본으로 생각하는 것이 좋습니다.
  • 가독성 중요할 때: CASE가 더 구조적이며 주석 추가도 용이합니다.

예제: 주문 상태 분류

다음은 주문 상태 코드를 사용자 친화적인 설명으로 변환하는 예시입니다.

DECODE 사용:

SELECT
    ORDER_ID,
    DECODE(STATUS, 'P', '결제대기', 'S', '배송중', 'D', '배송완료', '기타') AS STATUS_DESC
FROM ORDERS;

CASE 사용:

SELECT
    ORDER_ID,
    CASE
        WHEN STATUS = 'P' THEN '결제대기'
        WHEN STATUS = 'S' THEN '배송중'
        WHEN STATUS = 'D' THEN '배송완료'
        ELSE '기타'
    END AS STATUS_DESC
FROM ORDERS;

두 방식 모두 결과는 동일하지만, CASE는 논리적으로 더 유연하게 작성할 수 있다는 장점이 있습니다.

결론

  • DECODE는 간결하고 빠르지만 단순한 조건에만 적합합니다.
  • CASE는 복잡한 조건, 가독성, 유지보수 측면에서 우위에 있습니다.
  • 실무에서는 대부분 CASE를 사용하는 것이 더 안전하고 유연합니다.

각 상황에 맞게 적절한 문법을 선택하면 SQL의 가독성과 유지보수성을 크게 높일 수 있습니다.

#DECODE문 #CASE문 #오라클조건문 #SQL분기 #오라클CASE #오라클쿼리작성 #SQL표현식

반응형

MERGE 문을 활용한 UPSERT – 오라클에서 조건부 INSERT/UPDATE 처리하는 방법

Posted by heoncode
2025. 7. 21. 13:34 오라클 실무 쿼리 튜닝
반응형

데이터를 조건에 따라 삽입하거나 갱신하는 작업은 실무에서 자주 요구되는 패턴입니다. 특히 대상 테이블에 해당 조건의 데이터가 존재하면 UPDATE, 없으면 INSERT하는 작업은 'UPSERT'라고도 불립니다. 오라클에서는 이 작업을 MERGE 문으로 효과적으로 처리할 수 있습니다.

MERGE 문 기본 구조

오라클의 MERGE 문은 USING절을 통해 비교할 대상 데이터를 지정하고, ON절에서 조건을 비교한 뒤, WHEN MATCHED, WHEN NOT MATCHED절을 통해 조건에 따라 UPDATE 또는 INSERT를 수행합니다.

MERGE INTO 대상테이블 A
USING (서브쿼리 또는 임시테이블) B
ON (A.기준컬럼 = B.기준컬럼)
WHEN MATCHED THEN
  UPDATE SET A.컬럼1 = B.컬럼1
WHEN NOT MATCHED THEN
  INSERT (컬럼1, 컬럼2) VALUES (B.컬럼1, B.컬럼2);

실전 예제: 고객 포인트 데이터 갱신

예를 들어 고객 포인트 정보를 업데이트하거나, 신규 고객은 삽입하고 싶을 때 다음과 같은 방식으로 사용할 수 있습니다.

MERGE INTO CUSTOMER_POINT T
USING (
  SELECT 'C101' AS CUST_ID, 150 AS POINT FROM DUAL
) S
ON (T.CUST_ID = S.CUST_ID)
WHEN MATCHED THEN
  UPDATE SET T.POINT = T.POINT + S.POINT
WHEN NOT MATCHED THEN
  INSERT (CUST_ID, POINT) VALUES (S.CUST_ID, S.POINT);

이 쿼리는 고객 ID가 'C101'인 고객이 이미 존재하면 해당 고객의 포인트를 누적 업데이트하고, 존재하지 않으면 새로 삽입합니다.

WHERE 조건으로 세분화하기

WHEN MATCHED 절에는 AND 조건을 추가하여 더욱 세밀하게 UPDATE 조건을 제한할 수 있습니다.

WHEN MATCHED AND T.POINT < 1000 THEN
  UPDATE SET T.POINT = T.POINT + S.POINT

이렇게 하면 포인트가 일정 기준 이하일 때만 갱신되도록 설정할 수 있습니다.

MERGE 문 사용 시 주의사항

  • ON 조건은 중복되지 않도록 고유 식별자가 필요합니다. 중복되면 ORA-30926 에러가 발생할 수 있습니다.
  • USING절은 단일 로우를 보장하거나, 반드시 JOIN 대상이 고유해야 합니다.
  • 트리거가 설정된 테이블에 사용 시, INSERT/UPDATE 트리거가 모두 작동하므로 주의가 필요합니다.
  • DML 성능 튜닝이 필요할 경우, MERGE 문도 힌트 사용이 가능합니다 (/*+ MERGE(...) */ 등).

실무 활용 팁

  • 로그 데이터를 기반으로 특정 조건에 맞게 집계 테이블을 갱신할 때 매우 유용합니다.
  • 대량 배치 처리 시 INSERT와 UPDATE를 분리하는 것보다 MERGE로 통합하는 것이 트랜잭션 관리와 성능 면에서 이점이 있습니다.
  • 반복적인 IF EXISTS → UPDATE ELSE INSERT 패턴을 코드로 구현하는 대신 MERGE로 간결하게 대체 가능합니다.

UPSERT는 단순한 테이블 갱신이지만, 실수 없이 안정적으로 처리하려면 MERGE 구문의 조건 구성과 예외 처리에 신경 써야 합니다. 위 예제를 바탕으로 업무 환경에 맞게 수정하여 적용할 수 있습니다.

#MERGE문 #UPSERT #오라클쿼리 #OracleSQL #조건부갱신 #SQL실무 #SQL튜닝 #INSERTUPDATE

반응형