더북(TheBook)

30과 90번 부서 사원에 대한 급여를 window 절을 사용해 다양한 형식으로 산출해 보자.

입력

    SELECT department_id, emp_name, hire_date, salary,
           SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_Date
                             ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
                             ) AS all_salary,
           SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_Date
                             ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
                             ) AS first_current_sal,
           SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_Date
                             ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
                             ) AS current_end_sal
      FROM employees
     WHERE department_id IN (30, 90);
그림 7-25 window 절을 이용한 급여 합계

파티션은 부서별로 나눴고 정렬은 입사일자 순으로 되어 있다. all_salary 컬럼 값은 시작 위치가 UNBOUNDED PRECEDING, 즉 부서별 입사일자가 가장 빠른 사원, 끝 위치는 UNBOUNDED FOLLOWING, 입사일자가 가장 최근인 사원이 되어 부서별 급여 총합이 모든 로우에 걸쳐 출력되었다. first_current_sal 컬럼 값은 가장 입사가 빠른 사원부터 현재 로우까지이므로 사원별 급여의 누적 합계가 계산된 것을 알 수 있다. 반면 current_end_sal 컬럼 값은 현재 로우부터 입사가 가장 늦은 사원까지 급여 총합계가 계산되므로 누적 합계가 역으로 산출되었음을 확인할 수 있다.

이번에는 ROWS 대산 RANGE를 사용해 보자. RANGE는 로우 단위가 아니라 논리적 구간을 나누는데 ROWS에서 사용한 모든 옵션을 사용할 수 있을 뿐만 아니라, 숫자와 날짜 형태로 범위를 줄 수 있다. 다음의 쿼리를 살펴 보자.

입력

    SELECT department_id, emp_name, hire_date, salary,
           SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_Date
                             RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
                             ) AS all_salary,
           SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_Date
                             RANGE 365 PRECEDING
                             ) AS range_sal1,
           SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_Date
                             RANGE BETWEEN 365 PRECEDING AND CURRENT ROW
                             ) AS range_sal2
      FROM employees
     WHERE department_id = 30;
그림 7-26 RANGE window 절 예제 1

range_sal1 컬럼은 BETWEEN을 명시하지 않았으므로 RANGE 365 PRECEDING이 시작 위치가 되고 끝 위치는 현재 로우가 된다. 그렇다면 365 PRECEDING의 의미는 뭘까? RANGE를 사용했을 때 ORDER BY 절에서 사용한 컬럼 값에 대해 상수로 범위를 줄 수 있는데, 입사일자로 정렬을 했으므로 365 PRECEDING은 각 로우의 입사일 기준으로 365일, 즉 1년 이하에 속하는 입사일을 가진 로우가 시작 위치가 된다. Den의 경우는 자신이 시작 위치가 되므로 11,000, Alexander는 Den의 입사일이 1년 이하에 속하므로 ‘11,000 + 3,100 = 14,100’으로 계산됐다. 하지만 Sigal의 입사일은 2005년 7월 24일이고 1년 이하에 속한 사원이 없으므로 자신의 급여인 2,800만 출력된 것이다. range_sal2는 BETWEEN을 명시했지만 끝 위치가 현재 로우이므로 range_sal1과 동일한 값을 계산해 보여주고 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.