Infra & Security Eng/Database Engineering
인라인 뷰 Top-N 분석과 RANK 개념과 실습
엔지니어 E
2026. 2. 12. 12:12
반응형

Top-N 분석의 개념
| Top-N 분석은 말 그대로 전체 데이터 중에서 '가장 점수가 높은 상위 N명' 혹은 가장 저렴한 하위 N개 처럼 정렬된 결과의 일부분만 골라내는 방법 이다 SELECT ROWNUM, [컬럼, 컬럼, ...] -- 3. [최종 출력] 번호표(ROWNUM)와 보고 싶은 정보를 화면에 보여준다. FROM ( -- 1. [데이터 준비] 정렬된 "임시 명단"을 먼저 만든다. (인라인 뷰) SELECT ... ORDER BY ... -- ★ 중요: 여기서 미리 원하는 순서대로 줄을 세워야 한다! ) WHERE ROWNUM <= N; -- 2. [가위질] 위에서부터 N번째 사람까지만 남기고 나머지는 자른다. |
인라인 뷰를 이용한 Top-N 실습하기
| 실습하기 가장 높은 급여를 받는 3인을 검색 한다 SELECT ROWNUM, eno, ename, sal -- 3. [출력] 번호표(ROWNUM)와 사번, 이름, 급여를 화면에 보여줌 FROM ( -- 1. [정렬] 급여순으로 이미 줄을 세워놓은 가상 테이블(인라인 뷰) SELECT eno, ename, sal FROM emp ORDER BY sal DESC -- 내림차순(DESC) 정렬: 큰 숫자(고급여)가 위로 오게 함 ) WHERE ROWNUM <= 3; -- 2. [차단] 위에서부터 딱 3번까지만 통과시키고 나머지는 버림 |
| * 여기서 인라인뷰를 사용하는 이유는? 정렬(ORDER BY)는 SQL에서 가장 마지막에 일어나는 작업이고 번호 매기기 (RWONUM)은 정렬보다 먼저 일어난다. 따라서 번호를 매기기 전에 미리 정렬을 완료해 두려면, 정렬 전용 세상을 따로 만드는 인라인 뷰가 반드시 필요하다. 1. 인라인 뷰가 없을 때 발생하는 문제 만약 인라인 뷰 없이 일반적인 쿼리로 상위 3명을 뽑으려고 하면 컴퓨터는 이렇게 행동 한다 순서 1 (FROM): 전체 사원 데이터를 가져온다. 순서 2 (WHERE): 정렬도 안 된 상태에서 무작위로 먼저 도착한 3명을 자른다. (ROWNUM <= 3) 순서 3 (SELECT): 그 3명에게 번호를 매긴다. 순서 4 (ORDER BY): 이미 잘려나간 3명 안에서만 급여 순으로 정렬한다. 결과: 전체에서 급여가 가장 높은 3명이 나오는 게 아니라, 운 좋게 먼저 뽑힌 3명 중에서의 순위가 나온다 (틀린 데이터) 2. 인라인 뷰를 썼을 때의 해결책 인라인 뷰(( ))를 사용하면 컴퓨터의 실행 순서를 우리가 강제로 바꿀 수 있다 순서 1 (인라인 뷰 실행): 괄호 안을 먼저 실행해서 전체 사원을 급여 높은 순으로 완벽하게 정렬한다 순서 2 (FROM): 이미 정렬이 끝난 '완성된 명단'을 통째로 가져온다 순서 3 (WHERE): 이미 정렬되어 있으므로, 위에서부터 1, 2, 3등을 순서대로 자른다 결과: 전체 사원 중 급여가 가장 높은 진짜 상위 3명이 추출된다 |
RANK()를 이용한 순위 검색
| 순위 함수 3개 종류 RANK() OVER ([PARTITION BY 컬럼,컬럼 ...] ORDER BY ......) DENSE_RANK() OVER ([PARTITION BY 컬럼,컬럼 ...] ORDER BY ......) ROW_NUMBER() OVER ([PARTITION BY 컬럼,컬럼 ...] ORDER BY ......) 1.RANK(): 중복된 인원수만큼 숫자를 건너뛴다 공동 순위가 나오면, 그뒤의 등수는 중복된 사람 수만큼 뒤로 밀려난다 데이터: 100점, 90점, 90점, 80점 순위 계산: 1. 100점->1등 2. 90점-> 2등 (공동) 3. 90점-> 2등 (공동) 4. 80-> 4등(3등은사라짐, 앞에서 2명이 2등을 차지 했으므로 3이라는 숫자를 건너뛰고 4로 점프함 2. DENSE_RANK(): 중복이 있어도 숫자를 비우지 않는다 Dense는 밀집된 이라는 뜻이다. 공동 순위가 몇 명잉 나오든 상관없이 그 다음 숫자를 바로 이어서 쓴다 데이터: 100점, 90점, 90점, 80점 순위 계산: 1.100->1등 2. 90점-> 2등(공동) 3. 90점-> 2등(공동) 4.80점-> 3등(숫자가 이어짐. 앞 사람들이 공동 2등이었어도 상관없이 다음 순위는 그냥 3이다 3. ROW_NUMBER(): 중복을 인정하지 않고, 번호를 매긴다 값이 같더라도 무조건 고유한 번호(1,2,3,4)를 붙인다 데이터: 100점, 90점, 90점, 80점 순위 계산: 1.100점->1번 2. 90점-> 2번 3.90점->3번(90점으로 점수가 같지만, 번호는 다르게 부여됨) 4. 80점-> 4번 |
📊 한눈에 보는 요약표
| 점수 | RANK (건너뜀) | DENSE_RANK (연속) | ROW_NUMBER (고유) |
| 100 | 1 | 1 | 1 |
| 90 | 2 | 2 | 2 |
| 90 | 2 | 2 | 3 |
| 80 | 4 (3 생략) | 3 (2 다음 3) | 4 |
Ranking 검색 실습하기
![]() 급여 순위를 검색한다 SELECT eno, ename, sal, RANK() OVER (ORDER BY sal DESC) RANK, -- 중복 시 공동 순위 부여, 다음 순위는 중복 수만큼 건너뜀 (1, 2, 2, 4...) DENSE_RANK() OVER (ORDER BY sal DESC) DRANK, -- 중복 시 공동 순위 부여, 다음 순위는 건너뛰지 않고 이어서 매김 (1, 2, 2, 3...) ROW_NUMBER() OVER (ORDER BY sal DESC) RRANK FROM emp; -- 중복과 관계없이 데이터 출력 순서대로 고유 번호 부여 (1, 2, 3, 4...) ![]() 사원의 년봉을 순위별로 검색한다 SELECT RANK() OVER (ORDER BY sal*12+NVL(comm,0) DESC) RRANK, -- 1. 연봉 기준 내림차순으로 중복 건너뛰기 순위(RANK) 계산 eno, -- 2. 사번 출력 ename, -- 3. 이름 출력 sal*12+NVL(comm,0) 연봉 -- 4. 연봉 계산(월급*12 + 보너스) 및 별칭 부여 FROM emp; -- 5. emp 테이블로부터 데이터 추출 |

