Null 속성의 이해

2023. 3. 6. 10:05SQL/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 허용 여부를 판단해야 합니다.