BookmarkSubscribeRSS Feed

PROC SQL 활용예시 2

Started 4 weeks ago by
Modified 4 weeks ago by
Views 123

이번 글은 PROC SQL 활용예시 1 의 이어지는 글로 실무에서 활용할 수 있는 서브쿼리와 같은 결과를 출력할 수 있는 방안을 비교하는 예시에 대해서 알아보겠습니다.

 

Subquery(서브쿼리)란, 하나의 SQL문 안에 포함된 또 다른 SELECT 문 입니다. 쿼리 안에 또 다른 쿼리를 넣는 기법으로 특정 조건을 대상을 필터링 하거나, 집계된 값을 기준으로 기존의 데이터를 비교할 때, 유용하게 사용됩니다.

이번 게시글도 사원번호, 이름, 근속연수, 부서, 직급, 급여, 성과등급, 근무지, 고용형태 순으로 가상의 15명 employee_sample 데이터를 활용하겠습니다.

 

 

data employee_sample;
    length person_id 8
           name $10
           department $12
           position $10
           performance $1
           location $10
           hire_type $8;
           
    input person_id
          name $
          tenure
          department $
          position $
          salary
          performance $
          location $
          hire_type $;
          
datalines;
1001 Kim   1  HR        Staff      4200 B Seoul   Regular
1002 Lee   3  Finance   Senior     5200 A Seoul   Regular
1003 Park  5  IT        Senior     6000 A Busan   Regular
1004 Choi  2  Marketing Staff      4100 C Seoul   Contract
1005 Jung  7  IT        Manager    7500 A Seoul   Regular
1006 Kang  4  Finance   Staff      4800 B Incheon Regular
1007 Yoon 10  HR        Manager    7800 A Seoul   Regular
1008 Jang  6  Sales     Senior     6200 B Daegu   Regular
1009 Lim   1  Sales     Staff      4000 C Seoul   Intern
1010 Han   8  IT        Manager    8000 A Busan   Regular
1011 Shin  3  Marketing Senior     5300 B Seoul   Regular
1012 Oh    9  Finance   Manager    8200 A Seoul   Regular
1013 Seo   2  HR        Staff      4300 B Incheon Contract
1014 Kwon 12  Sales     Director   9500 A Seoul   Regular
1015 Baek  5  IT        Senior     6100 B Daejeon Regular
;
run;

 

 

 

■ 부서별 급여 순위 매기기

방법1) PROC SQL 의 Subquery 방식으로 처리

 

 

proc sql;
    select 
        department,
        name,
        salary,
        (select count(*) 
         from work.employee_sample as b 
         where a.department = b.department and b.salary > a.salary) + 1 as dept_rank
    from work.employee_sample as a
    order by department, dept_rank;
quit;

 

 

부서별로 급여 순위를 계산하고 서브쿼리를 활용하여 같은 부서 (a.department = b.department)에서 비교를 하여 급여가 더 높은 직원 (b.salary > a.salary) 일 경우 그 사람 수를 count 합니다.

부서별로 묶고 (order by department, dept_rank) 순위를 오름차순으로 정렬합니다.

 

 

 

image.png

 

 

위 구문은 Subquery 를 활용한 예시로 Rank 구현 방식입니다.

간단한 조회용 쿼리 작성에 유용하고 다른 조건들과 결합하기 쉽지만, 데이터가 많을 수록 행마다 Subquery 를 실행해 성능이 저하될 수 있는 단점이 있습니다.

방법2) Proc Rank문 활용

 

PROC SORT를 통해 데이터를 부서별로 정렬한 뒤, PROC RANK를 실행합니다. 이때 descending 옵션을 사용하여 높은 금액이 순위가 1등이 되도록 설정합니다.

 

 

proc sort data=work.employee_sample;
    by department descending salary;
run;

proc rank data=work.employee_sample 
          out=salary_rank 
          descending;
    by department;   
    var salary;      
    ranks dept_rank; 
run;

image.png

 

 

 

  • descending: descending 옵션이 없으면 기본적으로 ascending이 default 로 설정되어 가장 작은 급여가 1순위로 보여지게 됩니다.

  • by department: 데이터 스텝의 by 구문과 비슷한 구문으로 부서별로 그룹화하여 순위를 설정할 수 있습니다. 부서가 바뀔 때마다 순위를 1등부터 다시 시작하게 합니다.

  • var salary: 어떤 값을 기준으로 순위를 매길지 결정합니다.

  • ranks dept_rank: 기존의 salary 값을 덮어쓰지 않고, dept_rank라는 새로운 컬럼에 순위 숫자를 저장합니다.

PROC Rank 문을 활용해 대용량 데이터에서 성능이 좋아 순위를 계산하기에는 용이하지만, 정렬(SORT) 과정이 필요하다라는 단점이 있습니다.