이번 글은 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) 순위를 오름차순으로 정렬합니다.
위 구문은 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;
descending: descending 옵션이 없으면 기본적으로 ascending이 default 로 설정되어 가장 작은 급여가 1순위로 보여지게 됩니다.
by department: 데이터 스텝의 by 구문과 비슷한 구문으로 부서별로 그룹화하여 순위를 설정할 수 있습니다. 부서가 바뀔 때마다 순위를 1등부터 다시 시작하게 합니다.
var salary: 어떤 값을 기준으로 순위를 매길지 결정합니다.
ranks dept_rank: 기존의 salary 값을 덮어쓰지 않고, dept_rank라는 새로운 컬럼에 순위 숫자를 저장합니다.
PROC Rank 문을 활용해 대용량 데이터에서 성능이 좋아 순위를 계산하기에는 용이하지만, 정렬(SORT) 과정이 필요하다라는 단점이 있습니다.