데이터베이스(DB)/SQLD

[SQLD 1-2-4] 데이터 모델과 SQL - Null 속성의 이해

송기동 2024. 5. 11. 18:12
728x90

 

위의 주문모델을 보면 주문금액과 주문최소금액이 Null 허용인 것을 알 수 있다.

Null 값을 가질 수 있는 속성은 몇가지 특성이 존재한다.

 

1. Null 값의 연산은 언제나 Null이다.

Null값은 공백이나 숫자0과는 전혀 다른 의미이다.

아직 정의되지 않은 미지의 값 또는 현재 데이터를 입력하지 못하는 경우를 의미한다.

즉, Null은 값이 존재하지 않음을 말한다.

 

 

위와 같은 데이터가 있다고 가정하고, 다음과 같은 SQL문 값을 예측해보자.

SELECT 주문금액 - 주문취소금액 COL1,
	 NVL(주문금액 - 주문취소금액, 0) COL2,
   	 NVL(주문금액, 0) - NVL(주문취소금액, 0) COL3
FROM 주문

 

SQL에 익숙하지 않은분들을 위해 위의 SQL문을 추가 설명 하자면,

주문테이블에 있는(FROM) 내용을 조회(SELECT) 하는 쿼리문이다.

조회할 내용은 첫번째줄 "주문금액 - 주문취소금액" 의 값을 COL1 라는 이름으로 출력하고

두번째줄 "NVL(주문금액 - 주문취소금액, 0)" 의 값을 COL2 라는 이름으로 출력하고

세번째줄 "NVL(주문금액, 0) - NVL(주문취소금액, 0)" 의 값을 COL3 라는 이름으로 출력한다.

여기서 NVL 함수란, NVL(A, B) 일때 A가 NULL이면 B를 반환하는 함수이다.

 

 

위의 주문 테이블을 대입하여 대하여 한줄씩 풀어보자.

주문테이블 첫번째행(주문번호 'A10001'인 행)을 계산해보자.

COL1 = 주문금액 - 주문취소금액

- 첫번째행의 COL1 = 100000 - 20000 이므로, 80000이 된다.

 

COL2 = NVL(주문금액 - 주문취소금액, 0)

- 첫번째행의 주문금액-주문취소금액 = 100000-20000=80000 이므로,

- NVL(80000,0) = '80000'이 Null이 아니므로 그대로 80000을 반환한다.

 

COL3 = NVL(주문금액, 0) - NVL(주문취소금액, 0)

- 첫번째행을 대입하면 NVL(100000,0) - NVL(20000,0) 이다.

- '100000'이 Null이 아니므로 그대로 100000, '20000'이 Null이 아니므로 그대로 20000

- 따라서 100000-20000=80000 이다.

 

두번째 행(주문번호 'A10002'인 행)을 계산해보자.

COL1 = 주문금액 - 주문취소금액

- 두번째행은 주문금액이 15000이고, 주문최소금액이 Null값이다.

- null값의 연산은 언제나 Null이므로 COL1의 값은 null이 된다.

 

COL2 = NVL(주문금액 - 주문취소금액, 0)

- 두번째행의 주문금액 - 주문취소금액은 윗줄에서 계산했듯 Null 이므로,

- NVL(Null, 0) 이고, Null 이므로 두번째인자인 '0'을 반환한다.

 

COL3 = NVL(주문금액, 0) - NVL(주문취소금액, 0)

- 두번째행을 대입하면 NVL(15000, 0) - NVL(Null, 0) 이다.

- 15000은 Null이 아니므로 15000을 반환하고, Null은 Null이므로 0을 반환하면

- 15000 - 0 = 15000 즉 COL3 값은 15000을 반환한다.

 

따라서 수행결과는 다음과 같다.


2. 집계함수는 Null 값을 제외하고 처리한다.

이번에는 다음과 같은 데이터가 있다고 가정하자.

 

주문취소금액이 없는 테이블이다. 이 테이블에 대해 다음과 같은 SQL 결과를 예측해보자.

SELECT SUM(주문금액) - SUM(주문취소금액) COL1,
	NVL(SUM(주문금액 - 주문취소금액), 0) COL2,
    	NVL(SUM(주문금액), 0) - NVL(SUM(주문취소금액), 0) COL3
FROM 주문

 

여기서 SUM(주문금액)은 주문금액을 모두 합산하라는 의미이다.

SUM함수 안에 Null이 있을 경우 값을 제외하고 처리한다.

위 테이블에 대하여 SQL문 한줄씩 풀어보자.

 

COL1 = SUM(주문금액)-SUM(주문취소금액)

- 먼저 주문금액의 합은 100000 + 15000 + 40000 + 45000 + 100000 = 300000 이다.

- 주문 취소금액은 모두 Null 이므로 SUM(주문취소금액)은 Null이 된다.

- 300000 - Null = Null 이므로 첫번째 값은 Null이 된다.

 

COL2 = NVL(SUM(주문금액 - 주문취소금액), 0) 

- 먼저 SUM(주문금액 - 주문취소금액) 부터 풀어보면,

- 첫번째 행부터 순서대로 100000 - Null, 15000 - Null, 40000 - Null, 45000 - Null, 100000 - Null 이다.

- Null의 연산은 Null 이므로 이 모든 값을 합해도 Null이 된다.

- 따라서 NVL(Null, 0) 이고, Null이므로 두번째 인자값인 0을 반환한다.

 

COL3 = NVL(SUM(주문금액), 0) - NVL(SUM(주문취소금액), 0)

- 먼저 SUM(주문금액)은 위에서 계산한바와 같이 300000이다.

- 따라서 NVL(300000, 0) 은 Null이 아니므로 300000을 반환한다.

- SUM(주문취소금액)은 위에서 계산한바와같이 Null이다.

- 따라서 NVL(Null, 0) 은 Null 이므로 두번째 인자값인 0을 반환한다.

- 즉 COL3 = 300000 - 0 = 300000 이다.

 

따라서 수행결과는 다음과 같다.


집계함수에 대하여 한가지 더 계산해보자. 다음과 같은 테이블이 있다.

 

위 데이터에 대하여 다음과 같은 SQL문의 결과를 예측해보자

SELECT SUM(주문취소금액) / COUNT(*) COL1,
	AVG(주문취소금액) COL2
FROM 주문

COUNT(*)은 데이터의 총 갯수를 말한다.

AVG함수는 평균값을 구하는 함수로, AVG(주문취소금액)은 주문취소금액의 평균값을 말한다.

 

쿼리문을 한줄씩 계산해보자.

COL1 = SUM(주문취소금액) / COUNT(*)

SUM(주문취소금액)은 20000 +10000 + 10000 + 10000 = 50000 이다.

집계함수에서 Null값은 빼고 계산하기 때문에 주문번호 A10002의 주문취소금액은 제외하고 계산하였다.

COUNT(*)은 여기에서는 데이터가 5개이므로 5이다.

ㅊ따라서 50000 / 5 = 10000 가 된다.

 

COL2 = AVG(주문취소금액)

AVG(주문취소금액)은 주문취소금액의 평균값을 말한다.

여기서 주문취소금액의 값의 평균값을 구하면, (20000 + 10000 + 10000 + 10000) / 4 = 12500 이 될것이다.

집계함수에서 null 값은 제외하고 계산하므로 평균 또한 null값을 제외한 4개 데이터의 평균값을 구했다.

 

따라서 수행결과는 다음과 같다.

 

 

 

출저 : SQL 전문가 가이드
728x90