2023. 3. 6. 10:05ㆍSQL/SQL 전문가 가이드(2020 개정판)
DBMS를 사용하다 보면 Null 값으로 인한 많은 특이사항들을 접하게 됩니다. Null 값이 가지는 특성을 이해하지 못한다면 데이터 오류를 경험할 수 있으므로 반드시 숙지해야 할 부분 중 하나입니다.
1. Null 값의 연산은 언제나 Null이다
Null 값은 '공백이나 숫자 0'과는 전혀 다른 의미입니다. '아직 정의되지 않은 미지의 값' 또는 '현재 데이터를 입력하지 못하는 경우', Null 값이 존재하지 않음을 의미합니다.
주문번호 | 주문금액 | 주문취소금액 |
1100001 | 100,000 | 20,000 |
1100002 | 15,000 |
SELECT 주문금액 - 주문취소금액 COL1
, NVL(주문금액-주문취소금액, 0) COL2
, NVL(주문금액, 0) - NVL(주문취소금액, 0) COL3
FROM 주문
COL1, COL2, COL3는 최종 주문금액을 구하는 산식입니다. 최종 주문금액은 각 주문의 주문금액에서 취소된 주문금액을 제외한 결과입니다.
SQL 수행 결과
COL1 | COL2 | COL3 |
80,000 | 80,000 | 80,000 |
0 | 15,000 |
Null 값이 포함되었을 경우 COL1, COL2, COL3의 결과가 모두 다르게 출력하는 것을 알 수 있습니다. 위 SQL 이해를 위해서는 NVL 함수를 알아야 합니다. NVL 함수는 첫 번째 인자값의 결과가 Null일 경우 두 번째 인자 값을 반환하는 함수입니다.
주문금액 - 주문취소금액 COL1 |
COL1은 최종주문금액을 구하기 위해 Null 값을 전혀 고려하지 않고, 주문금액에서 주문취소금액을 제외한 방식입니다.
NVL(주문금액 - 주문취소금액, 0) COL2 |
COL2는 주문금액에서 주문취소금액을 제외한 결과에 대해 NVL 처리를 했습니다.
NVL(주문금액, 0) - NVL(주문취소금액, 0) COL3 |
COL3은 각 속성별로 NVL 처리를 하고, 이후 주문금액에서 주문취소금액을 제외했습니다. Null에 대한 특성을 인지하지 않는다면 COL1, COL2처럼 잘못된 결과를 반환할 수 있다는 것을 숙지해야 합니다.
1. 집계함수는 Null 값을 제외하고 처리한다
주문 데이터
주문번호 | 주문금액 | 주문취소금액 |
1100001 | 100,000 | |
1100002 | 15,000 | |
1100003 | 40,000 | |
1100004 | 45,000 | |
1100005 | 100,000 |
주문취소금액은 전부 Null 값으로 아직 취소된 주문이 없는 상태입니다.
SELECT SUM(주문금액) - SUM(주문취소금액) COL1
, NVL(SUM(주문금액 - 주문취소금액), 0) COL2
, NVL(SUM(주문금액), 0) - NVL(SUM(주문취소금액), 0) COL3
FROM 주문
COL1, COL2, COL3는 최종주문금액 총합을 구하는 산식입니다. 최종주문금액은 각 주문의 주문금액에서 취소된 주문금액을 제외하고, 총합은 이를 합산한 결과입니다.
SQL 수행 결과
COL1 | COL2 | COL3 |
0 | 300,000 |
COL1, COL2, COL3은 모두 다른 결과를 출력합니다. SUM 함수는 정의된 칼럼의 값을 모두 합산하는 함수로서 Null 값이 들어올 경우 이는 제외하고, 처리합니다.
SUM(주문금액) - SUM(주문취소금액) COL1 |
COL1은 속성별로 SUM 함수로 합산을 먼저 수행하고, 총 주문금액에서 총 주문취소금액을 제외했습니다. 주문취소금액은 한 건도 존재하지 않기에 합산한 결과는 Null이 됩니다.
NVL(SUM(주문금액 - 주문취소금액), 0) COL2 |
COL2는 주문금액에서 주문취소금액을 제외한 결과를 SUM 함수로 합산하고, 최종결과가 Null일 경우 0으로 반환하는 NVL 처리를 했습니다. SUM(주문금액 - 주문취소금액)은 주문별로 '주문금액 - 주문취소금액'을 한 결과를 모두 합산하는 의미입니다.
NVL(SUM(주문금액), 0) - NVL(SUM(주문취소금액), 0) COL3 |
COL3은 각 속성별로 SUM 함수로 합산하고, 최종결과가 Null일 경우 0을 반환한 후, 총 주문금액에서 총 주문취소금액을 제외했습니다. NVL(SUM(주문금액), 0)은 주문금액을 모두 합산하고, 합산한 결과가 Null일 경우 0을 반환하라는 의미입니다. NVL(SUM(주문취소금액), 0) 역시 주문취소금액을 모두 합산하고, 결과가 Null일 경우 0을 반환하게 됩니다.
주문 데이터
주문번호 | 주문금액 | 주문취소금액 |
1100001 | 100,000 | 20,000 |
1100002 | 15,000 | |
1100003 | 40,000 | 10,000 |
1100004 | 45,000 | 10,000 |
1100005 | 100,000 | 10,000 |
평균 구하는 공식
평균 = 자료전체의합 / 자료의개수 |
자료의 개수에 Null 값을 포함해야 하는지 제외해야 하는지를 정의해야 평균을 구할 수 있습니다.
SELECT SUM(주문취소금액)/COUNT(*) COL1
, AVG(주문취소금액) COL2
FROM 주문
SQL 수행 결과
COL1 | COL2 |
10,000 | 12,500 |
NVL(SUM(주문취소금액), 0) / COUNT(*) COL1
COL1은 주문취소금액의 합계를 총건수로 나눴습니다.
AVG(주문취소금액) COL2
COL2는 평균값을 구하는 집계함수 AVG를 사용했습니다. 집계함수는 Null 값을 제외한다는 특성으로 '50,000/4'로 연산했습니다. 속성에 Null 값이 존재한다면 많은 사항을 고려해야 하며, 모델을 생성할 때 업무를 정확히 파악하여 Null 허용 여부를 판단해야 합니다.
'SQL > SQL 전문가 가이드(2020 개정판)' 카테고리의 다른 글
관계형 데이터베이스 개요 (0) | 2023.03.08 |
---|---|
본질식별자 vs. 인조식별자 (0) | 2023.03.07 |
모델이 표현하는 트랜잭션의 이해 (0) | 2023.03.05 |
관계(Relationship)와 조인(Join)의 이해 (2) | 2023.03.04 |
정규화(Normalization) (0) | 2023.03.03 |