리포트의 빈칸을 null이 아닌 zero로 표현하기 위해 nvk(iracke)/isnull(sql server)함수를 사용하는 경우가 많은데, 다중 행 함수를 사용하는 경우는 오히려 불필요한 부하가 발생하므로 굳이 nvl함수를 다중 행 함수 안에 사용할 필요가 없다.
다중 행 함수는 입력 값으로 전체 건수가 null값인 경우만 함수의 결과가 null이 나오고 전체 건수 중에서 일부만 null인 경우는 null인 행을 다중 행 함수의 대상에서 제외한다.예를 들면 100면중 10명의 성적이 null값일 때 평균을 구하는 다중 행 함수 avg를 사용하면 null값이 아닌 90명의 성적에 대해서 평균값을 구하게 된다.
case 표현 사용시 else 절을 생략하게 되면 default 값이 null이다.null은 연산의 대상이 아닌 반면, sum(case month when 1 then sal else 0 end) 처럼 else 절에서 0을 지정하면 불필요하게 0이 sum 연산에 사용되므로 자원의 사용이 많아진다.
가능한 else 절의 상수값을 지정하지 않거나 else절을 작성하지 않도록 한다.
오라클의 decode함수는 4번째 인자를 지정하지 않으면 null이 default로 할당된다.
oracle의 sum(nvl(sal,0))
sql server의 sum(isnull(sal,0))
불필요하게 nvl/isnull함수를 사용해 0으로 변환시켜 데이터 건수만큼의 연산이 일어나게 하는 것은 시스템의 자원을 낭비하는 일이다.리포트 출력 때 null이 아닌 0을 표시하고 싶은 경우에는 nvl(sum(sal),0) 이나 isnull(sum(sal),0)처럼 전체 sum의 결과가 null인 경우(대상 건수가 모두 null인 경우)에만 한번 nvl/isnull함수를 사용하면 된다.
SELECT TEAM_ID
, NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 ELSE 0 END),0) FW
, NVL(SUM(CASE POSITION WHEN 'MF' THEN 1 ELSE 0 END),0) MF
, NVL(SUM(CASE POSITION WHEN 'DF' THEN 1 ELSE 0 END),0) DF
, NVL(SUM(CASE POSITION WHEN 'GK' THEN 1 ELSE 0 END),0) GK
, COUNT(*) SUM
FROM PLAYER GROUP BY TEAM_ID;
CASE 표현의 ELSE 0, ELSE NULL 문구는
생략 가능하므로 다음과 같이 조금 더 짧게 SQL 문장을 작성할 수 있다. Default 값인 NULL이적용됨.
SELECT TEAM_ID
, NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 END),0) FW
, NVL(SUM(CASE POSITION WHEN 'MF' THEN 1 END),0) MF
, NVL(SUM(CASE POSITION WHEN 'DF' THEN 1 END),0) DF
, NVL(SUM(CASE POSITION WHEN 'GK' THEN 1 END),0) GK
, COUNT(*) SUM
FROM PLAYER GROUP BY TEAM_ID;
NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 ELSE 0 END),0) FW
NVL(SUM(CASE POSITION WHEN 'FW' THEN 1 END),0) FW