포스팅 목차
106. Find out the top 5 earner of company
* 최대 급여 수령자 상위 5명의 정보를 출력하시오.
- 관련예제 : 106번
- 파이썬 & R 패키지 호출 및 예제 데이터 생성 링크
|
1. Oracle(오라클)
개별 관측치를 기준으로 본인 급여보다 더 많은 급여를 수령하는 직원의 수를 카운트하여서 상위 5명의 정보를 출력한다.
Oracle Programming |
select *
from emp e
where 5 > (select count(*) from emp where sal > e.sal)
order
by sal desc;
Row_number() 함수
Oracle Programming |
select *
from ( select a.*, ROW_NUMBER() OVER(ORDER BY sal desc) AS row_num from emp a)
where row_num <= 5
2. Python Pandas(파이썬)
nlargest 함수를 사용하여서 emp 테이블에서 상위 급여 수령자 5명의 정보를 선택한다.
Python Programming |
emp.nlargest(5, 'sal')
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7839 | KING | PRESIDENT | NaN | 1981/11/17 | 5000 | NaN | 10 |
7788 | SCOTT | ANALYST | 7566.0 | 1982/12/09 | 3000 | NaN | 20 |
7902 | FORD | ANALYST | 7566.0 | 1981/12/03 | 3000 | NaN | 20 |
7566 | JONES | MANAGER | 7839.0 | 1981/04/02 | 2975 | NaN | 20 |
7698 | BLAKE | MANAGER | 7839.0 | 1981/03/01 | 2850 | NaN | 30 |
3. R Programming (R Package)
emp 테이블을 급여를 기준으로 내림차순으로 정렬 후 상위 급여 수령자 5명의 정보를 선택한다.
R Programming |
%%R
emp[order(-emp$sal),][1:5, ]
Results |
# A tibble: 5 x 8
empno ename job mgr hiredate sal comm deptno
<dbl> <chr> <chr> <dbl> <date> <dbl> <dbl> <dbl>
1 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
2 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
3 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
4 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
5 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
row_number 함수를 사용하여서 emp 테이블을 급여를 기준으로 내림차순으로 정렬 후 상위 급여 수령자 5명의 정보를 선택한다.
R Programming |
%%R
filter(emp, row_number(desc(sal)) <= 5)
Results |
# A tibble: 5 x 8
empno ename job mgr hiredate sal comm deptno
<dbl> <chr> <chr> <dbl> <date> <dbl> <dbl> <dbl>
1 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
2 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
3 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
4 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
5 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
4. R Dplyr Package
slice_max 함수를 사용하여서 emp 테이블을 급여를 기준으로 상위 급여 수령자 5명의 정보를 선택한다.
R Programming |
%%R
emp %>%
slice_max(sal, n = 5)
Results |
# A tibble: 5 x 8
empno ename job mgr hiredate sal comm deptno
<dbl> <chr> <chr> <dbl> <date> <dbl> <dbl> <dbl>
1 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
2 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
3 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
4 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
5 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
top_n 함수를 사용하여서 emp 테이블을 급여를 기준으로 상위 급여 수령자 5명의 정보를 선택한 후에 arrange 함수를 사용하여서 내림차순으로 정렬한다.
R Programming |
%%R
emp %>%
top_n(5, sal) %>%
arrange(desc(sal))
Results |
# A tibble: 5 x 8
empno ename job mgr hiredate sal comm deptno
<dbl> <chr> <chr> <dbl> <date> <dbl> <dbl> <dbl>
1 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
2 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
3 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
4 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
5 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
5. R sqldf Package
개별 관측치를 기준으로 본인 급여보다 더 많은 급여를 수령하는 직원의 수를 카운트하여서 상위 5명의 정보를 출력한다.
R Programming |
%%R
sqldf(" select *
from emp e
where 5 > (select count(*) from emp where sal>e.sal)
order
by sal desc;")
Results |
empno ename job mgr hiredate sal comm deptno
1 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
2 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
3 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
4 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
5 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
위 예제의 서브쿼리가 반환하는 값을 살펴보면 본인의 급여보다 더 많은 급여를 수려하는 직원을 카운트한다.
R Programming |
%%R
sqldf(" select (select count(*) from emp where sal>e.sal) upper_emp,
e.*
from emp e
order
by sal desc;") %>% head(7)
Results |
upper_emp empno ename job mgr hiredate sal comm deptno
1 0 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
2 1 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
3 1 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
4 3 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
5 4 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
6 5 7782 CLARK MANAGER 7839 1981-01-09 2450 NA 10
7 6 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30
개별 관측치를 기준으로 본인 급여보다 더 많은 급여를 수령하는 직원의 수를 카운트하여서 상위 5명을 선택 후 emp 테이블에서 해당 사원 정보를 추출한다.
R Programming |
%%R
sqldf("select a.* \
from emp a, \
( select a.EMPNO, \
a.sal, \
count(distinct b.EMPNO) cnt \
from emp a \
left join emp b \
on a.sal < b.sal \
group by \
a.EMPNO, \
a.sal \
having count(*) < 5 \
) b \
where a.empno = b.empno \
and a.sal = b.sal;")
Results |
empno ename job mgr hiredate sal comm deptno
1 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
2 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
3 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
4 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
5 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
ROW_NUMBER() 함수를 사용하여서 emp 테이블을 급여를 기준으로 내림차순으로 정렬 후 급여 상위 부터 조회 순번을 부여한 후에 상위 급여 수령자 5명의 정보를 선택한다.
R Programming |
%%R
sqldf("select *
from ( select *, ROW_NUMBER() OVER(ORDER BY sal desc) AS row_num from emp )
where row_num <= 5")
Results |
empno ename job mgr hiredate sal comm deptno row_num
1 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10 1
2 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20 2
3 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20 3
4 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20 4
5 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30 5
Rank() 함수를 사용하여서 emp 테이블을 급여를 기준으로 내림차순으로 정렬 후 급여 상위 부터 조회 순번을 부여한 후에 상위 급여 수령자 5명의 정보를 선택한다.
R Programming |
%%R
sqldf("select *
from ( select *, RANK() OVER(ORDER BY sal desc) AS row_rank from emp )
where row_rank <= 5")
Results |
empno ename job mgr hiredate sal comm deptno row_rank
1 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10 1
2 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20 2
3 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20 2
4 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20 4
5 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30 5
6. Python pandasql Package
Count() 함수
Python Programming |
ps.sqldf("select * from emp e where 5 > (select count(*) from emp where sal>e.sal) order by sal desc;")
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7839 | KING | PRESIDENT | NaN | 1981/11/17 | 5000 | None | 10 |
7788 | SCOTT | ANALYST | 7566.0 | 1982/12/09 | 3000 | None | 20 |
7902 | FORD | ANALYST | 7566.0 | 1981/12/03 | 3000 | None | 20 |
7566 | JONES | MANAGER | 7839.0 | 1981/04/02 | 2975 | None | 20 |
7698 | BLAKE | MANAGER | 7839.0 | 1981/03/01 | 2850 | None | 30 |
Python Programming |
ps.sqldf("select * from (select (select count(*) from emp where sal>e.sal) as row_rank,* from emp e ) where row_rank <5 order by sal desc")
Results |
row_rank | empno | ename | job | mgr | hiredate | sal | comm | deptno |
0 | 7839 | KING | PRESIDENT | NaN | 1981/11/17 | 5000 | None | 10 |
1 | 7788 | SCOTT | ANALYST | 7566.0 | 1982/12/09 | 3000 | None | 20 |
1 | 7902 | FORD | ANALYST | 7566.0 | 1981/12/03 | 3000 | None | 20 |
3 | 7566 | JONES | MANAGER | 7839.0 | 1981/04/02 | 2975 | None | 20 |
4 | 7698 | BLAKE | MANAGER | 7839.0 | 1981/03/01 | 2850 | None | 30 |
Python Programming |
ps.sqldf("select a.sal, \
count(*) cnt \
from emp a \
left join emp b \
on a.sal < b.sal \
group by \
a.sal \
having count(*) <= 5")
Results |
sal | cnt |
2450 | 5 |
2850 | 4 |
2975 | 3 |
3000 | 2 |
5000 | 1 |
7. R data.table Package
emp 테이블을 급여를 기준으로 내림차순으로 정렬 후 상위 급여 수령자 5명의 정보를 선택한다.
R Programming |
%%R
DT <- data.table(emp)
dept_DT <- data.table(dept)
salgrade_DT <- data.table(salgrade)
DT[order(-DT$sal),][1:5, ]
Results |
empno ename job mgr hiredate sal comm deptno
1: 7839 KING PRESIDENT NA 1981-11-17 5000 NA 10
2: 7788 SCOTT ANALYST 7566 1982-12-09 3000 NA 20
3: 7902 FORD ANALYST 7566 1981-12-03 3000 NA 20
4: 7566 JONES MANAGER 7839 1981-04-02 2975 NA 20
5: 7698 BLAKE MANAGER 7839 1981-03-01 2850 NA 30
8. SAS Proc SQL
개별 관측치를 기준으로 본인 급여보다 더 많은 급여를 수령하는 직원의 수를 카운트하여서 상위 5명의 정보를 출력한다.
SAS Programming |
%%SAS sas
PROC SQL;
CREATE TABLE STATSAS_1 AS
select *
from emp e
where 5 > (select count(*) from emp where sal > e.sal) order by sal desc;
QUIT;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 |
SAS Programming |
%%SAS sas
PROC SQL;
CREATE TABLE STATSAS_2 AS
select a.*
from emp a,
( select a.EMPNO,
a.sal,
count(distinct b.EMPNO) as cnt
from emp a
left join emp b
on a.sal < b.sal
group by
a.EMPNO,
a.sal
having count(*) < 5
) b
where a.empno = b.empno
and a.sal = b.sal;
QUIT;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 |
- SAS에서는 인라인뷰에서 ORDER BY를 사용하지 못하는 단점이 있음;
- 사전 정렬 후 monotonic() 사용;
- 통계분석연구회 카페;
- PROC SQL에서 중복제거는 일반적으로 SUBQUERY나 JOIN 으로 일반적으로 처리하지만, MONOTONIC() 함수로 처리해보았습니다;
- MONOTONIC은 메모리에서 처리 순서에 따라서 씨퀀스 방식이 달라지므로 권해드리는 방식은 아님을 알려드립니다;
- PROC SQL에서 MONOTONIC은 정식 지원 옵션은 아님;
- http://support.sas.com/kb/15/138.html;
- Usage Note 15138: Support for the MONOTONIC() function in PROC SQL;
- [ 참고 ]
- 데이터 중복제거(first. / last대안) - MAX , MIN : http://cafe.daum.net/statsas/3F8j/162
- [SQL] PROC SQL에서 nodupkye 사용(monotonic) : http://cafe.daum.net/statsas/3F8j/70
- [MAX] 변수중에 2번째 큰값 찾기 http://cafe.daum.net/statsas/3F8j/163;
- 사전 소팅 필수;
SAS Programming |
%%SAS sas
PROC SQL;
CREATE TABLE STATSAS_3 AS
select e.*
from emp e
order
by sal desc;
create table STATSAS_4 as
select a.*,
monotonic() as sal_rank
from STATSAS_3 a
HAVING sal_rank<=5; * HAVING CALCULATED sal_rank<=5;
QUIT;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno | sal_rank |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 | 1 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 | 2 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 | 3 |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 | 4 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 | 5 |
SAS Programming |
%%SAS sas
proc sql;
create table STATSAS_4(where=(monotonic()<=5)) as
select e.*
from emp e
order
by sal desc;
quit;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 |
SAS Programming |
%%SAS sas
proc sql;
select 1,
EMPNO,
SAL,
monotonic() As row_numb ,
min(calculated row_numb) as indicator
from EMP
group by 1
ORDER BY 3;
quit;
Results |
empno | sal | row_numb | indicator | |
1 | 7369 | 800 | 1 | 1 |
1 | 7900 | 950 | 12 | 1 |
1 | 7876 | 1100 | 11 | 1 |
1 | 7654 | 1250 | 5 | 1 |
1 | 7521 | 1250 | 3 | 1 |
1 | 7934 | 1300 | 14 | 1 |
1 | 7844 | 1500 | 10 | 1 |
1 | 7499 | 1600 | 2 | 1 |
1 | 7782 | 2450 | 7 | 1 |
1 | 7698 | 2850 | 6 | 1 |
1 | 7566 | 2975 | 4 | 1 |
1 | 7902 | 3000 | 13 | 1 |
1 | 7788 | 3000 | 8 | 1 |
1 | 7839 | 5000 | 9 | 1 |
[참고] 올림차순
SAS Programming |
%%SAS sas
PROC SQL;
CREATE TABLE STATSAS_5 AS
SELECT A.empno,
A.ename,
A.sal,
COUNT(B.empno)+1 AS RANK
FROM EMP A
LEFT JOIN EMP B
ON A.SAL > B.sal
GROUP BY
A.empno,
A.ename,
A.sal
HAVING RANK<=5;
QUIT;
PROC PRINT;RUN;
Results |
empno | ename | sal | RANK |
7369 | SMITH | 800 | 1 |
7521 | WARD | 1250 | 4 |
7654 | MARTIN | 1250 | 4 |
7876 | ADAMS | 1100 | 3 |
7900 | JAMES | 950 | 2 |
9. SAS Data Step
RANK 프로시져 사용;
SAS Programming |
%%SAS sas
PROC RANK DATA=EMP OUT=STATSAS_6(WHERE=(RANK<=5)) DESCENDING;
RANKS RANK;
VAR SAL ;
RUN;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno | RANK |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 | 4.0 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 | 5.0 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 | 2.5 |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 | 1.0 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 | 2.5 |
SAS Programming |
%%SAS sas
PROC SORT DATA=EMP OUT=EMP_1;
BY DESCENDING SAL;
RUN;
DATA STATSAS_7;
SET EMP_1;
BY DESCENDING SAL;
IF _N_ <=5;
RUN;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 |
SAS Programming |
%%SAS sas
PROC SORT DATA=EMP OUT=EMP_1;
BY DESCENDING SAL;
RUN;
DATA STATSAS_8;
SET EMP_1;
BY DESCENDING SAL;
RANK + 1;
IF RANK <=5;
RUN;
PROC PRINT;RUN;
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno | RANK |
7839 | KING | PRESIDEN | . | 1981-11-17 | 5000 | . | 10 | 1 |
7788 | SCOTT | ANALYST | 7566 | 1982-12-09 | 3000 | . | 20 | 2 |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | . | 20 | 3 |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | . | 20 | 4 |
7698 | BLAKE | MANAGER | 7839 | 1981-03-01 | 2850 | . | 30 | 5 |
10. Python Dfply Package
row_number() 함수
Python Programming |
emp >> mutate(row_rank=row_number(X.sal, ascending=False)) >> filter_by(X.row_rank <= 5) >> arrange(~X.sal)
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno | row_rank |
7839 | KING | PRESIDENT | NaN | 1981/11/17 | 5000 | NaN | 10 | 1.0 |
7788 | SCOTT | ANALYST | 7566.0 | 1982/12/09 | 3000 | NaN | 20 | 2.0 |
7902 | FORD | ANALYST | 7566.0 | 1981/12/03 | 3000 | NaN | 20 | 3.0 |
7566 | JONES | MANAGER | 7839.0 | 1981/04/02 | 2975 | NaN | 20 | 4.0 |
7698 | BLAKE | MANAGER | 7839.0 | 1981/03/01 | 2850 | NaN | 30 | 5.0 |
min_rank() 함수
Python Programming |
emp >> mutate(row_rank=min_rank(X.sal, ascending=False)) >> filter_by(X.row_rank <= 5) >> arrange(~X.sal)
Results |
empno | ename | job | mgr | hiredate | sal | comm | deptno | row_rank |
7839 | KING | PRESIDENT | NaN | 1981/11/17 | 5000 | NaN | 10 | 1.0 |
7788 | SCOTT | ANALYST | 7566.0 | 1982/12/09 | 3000 | NaN | 20 | 2.0 |
7902 | FORD | ANALYST | 7566.0 | 1981/12/03 | 3000 | NaN | 20 | 2.0 |
7566 | JONES | MANAGER | 7839.0 | 1981/04/02 | 2975 | NaN | 20 | 4.0 |
7698 | BLAKE | MANAGER | 7839.0 | 1981/03/01 | 2850 | NaN | 30 | 5.0 |
[SQL, Pandas, R Prog, Dplyr, SQLDF, PANDASQL, DATA.TABLE] SQL EMP 예제로 만나는 테이블 데이터 전처리 방법 리스트
'통계프로그램 비교 시리즈 > 프로그래밍비교(Oracle,Python,R,SAS)' 카테고리의 다른 글
[데이터 추출] 관측치 최대값(MAX) 리스트 추출 - 107 (0) | 2022.12.04 |
---|---|
[데이터 정렬 - 내림차순 정렬] 수치형 데이터를 기준으로 내림차순 정렬 - 37 (오라클 SQL, R, Python, SAS) (0) | 2022.10.31 |
[데이터 추출] Left Join 과 데이터 상하 결합(UNION) - 105 (0) | 2022.10.03 |
[데이터 추출] 비등가 FULL 조인(NON-EQUI FULL JOIN)을 통한 데이터 결합 및 데이터 정렬(SORT) - 104 (0) | 2022.10.02 |
[데이터 추출] 비등가 FULL 조인(NON-EQUI FULL JOIN)을 통한 데이터 결합 - 103 (0) | 2022.10.02 |
댓글