SELECT NUM
, VALUE
FROM (
SELECT TRUNC(DBMS_RANDOM.VALUE(1,1000)) NUM
, DECODE(MOD(TRUNC(DBMS_RANDOM.VALUE(1,1000)) ,2),0,NULL
,TRUNC(DBMS_RANDOM.VALUE(1,1000))) VALUE --짝수면 NULL
FROM DUAL
CONNECT BY LEVEL <=10
);
짝수면 NULL이 나오게 했다.
SELECT
DISTINCT AVG(VALUE) OVER() AVG1 --NULL포함 안함
, AVG(NVL(VALUE,0)) OVER() AVG2 -- NULL포함
, SUM(VALUE) OVER() / COUNT(VALUE) OVER() AVG3 --NULL포함 안함
, SUM(VALUE) OVER() / COUNT(*) OVER() AVG4 --카운트만 NULL포함
, SUM(VALUE) OVER() / COUNT(NVL(VALUE,0)) OVER() AVG5 -- 카윤트만 NULL 포함
, COUNT(VALUE) OVER() CN1
, COUNT(1) OVER() CN2
FROM (
SELECT TRUNC(DBMS_RANDOM.VALUE(1,1000)) NUM
, DECODE(MOD(TRUNC(DBMS_RANDOM.VALUE(1,1000)) ,2),0,NULL
,TRUNC(DBMS_RANDOM.VALUE(1,1000))) VALUE --짝수면 NULL
FROM DUAL
CONNECT BY LEVEL <=10
);
기본적으로 집계함수는 NULL 값을 제외한다. 따라서 AVG함수나, COUNT함수는 주의해서 사용해야 한다.
NULL인 값을 포함해서 계산을 하고 싶은 경우도 많기 때문이다.
추가로 집계함수의 NULL 처리 방식을 이해하면 아래 중 무엇이 잘못된 사용 방식인지 판별할 수 있다.
SELECT SUM(NVL(123,0)) FROM DUAL;
SELECT NVL(SUM(123), 0) FROM DUAL;
1번 째의 경우 나름 생각한다고 NULL처리를 했지만 DB에 불필요한 부하를 주게 된다.
내부적으로 NULL을 처리하는데 개발자가 NVL을 또 주었으니 불필요한 연산이 들어가게 된다.
이게 행이 많고, 집계함수를 몇 십개 쓴다고 생각해보자.
'개발 > 오라클 SQL' 카테고리의 다른 글
지정 요일 주차 구하기 (1) | 2023.02.01 |
---|---|
WINDOW함수와 DISTINCT조합 (0) | 2023.01.19 |
컬럼 <=> 행 변환 (0) | 2023.01.13 |
숫자 함수 응용 (0) | 2023.01.10 |
자주 쓰는 함수 모음 (1) | 2023.01.07 |