01. TOP N QUERY
- 페이징 처리를 효과적으로 수행하기 위해 사용
- 전체 결과에서 특정 N개 추출
- 예: 성적 상위자 3명
02. TOP-N 행 추출 방법
- ROWNUM
- RANK
- FETCH
- TOP N(SQL Server)
03. ROWNUM
- 출력된 데이터 기준으로 행 번호 부여
- 절대적인 행 번호가 아닌 가상의 번호 → 특정 행을 지정할 수 없음(= 연산 불가)
- 첫 번째 행이 증가한 이후 할당 → '>' 연산자 사용 불가(0 은 가능)
SELECT ROWNUM, emp.*
FROM emp
WHERE sal >= 1500; --ROWNUM을 출력 형태
* 잘못된 사용
SELECT *
FROM emp
WHERE ROWNUM > 1; --잘못된 사용, 크기 조건 전달 불가
SELECT *
FROM emp
WHERE ROWNUM = 4; --잘못된 사용2, 항상 불변하는 절대적인 번호가 아니므로 '='연산자는 단독 전달 불가
* 올바른 사용
SELECT empno, ename, deptno, sal
FROM emp
WHERE ROWNUM <= 5; --올바른 사용 방법
- EQUAL 비교 시 작다(<)와 함께 사용 → 1번부터 순서대로 뽑을 수 있음, 출력 가능함
- 정렬 순서에 따라 출력되는 ROWNUM이 달라짐
** 잘못된 예 1: emp 테이블에서 급여가 높은 순서대로 상위 5명의 직원 정보 출력 **
SELECT empno, ename, deptno, sal
FROM emp
WHERE ROWNUM <= 5
ORDER BY sal DESC;
- WHERE 절에 의해 먼저 5개를 추출 뒤 이 결과 집합에 대해 정렬 수행
- 해결 방법: 먼저 서브쿼리를 사용(인라인뷰)하여 sal에 대해 내림차순 정렬을 한 후 상위 5개를 추출
SELECT *
FROM (SELECT * --서브쿼리로 정렬 먼저 수행
FROM emp
ORDER BY sal DESC)
WHERE ROWNUM <= 5 --정렬된 컬럼에서 상위 5 추출
ORDER BY sal DESC;
- ROWNUM이 결정되기 전에 먼저 데이터 정렬 순서를 바꿔놓는 방법
** 잘못된 예 2: 테이블에서 급여가 높은 순서대로 4~6번 째 해당하는 직원 정보 출력 **
SELECT *
FROM (SELECT *
FROM emp
ORDER BY sal DESC)
WHERE ROWNUM BETWEEN 4 AND 6
ORDER BY sal DESC;
- ROWNUM 시작 값(1)이 정의되지 않았으므로 1을 건너뛰고 그 다음 행 번호에 대한 추출 불가
- 해결 1 : 인라인 뷰에서 각 행마다 순위를 직접 부여
SELECT *
FROM (SELECT ROWNUM AS rn, A.* --각 행마다 순위를 직접 부여
FROM emp
ORDER BY sal DESC) A) B --순위가 추가된 테이블로
WHERE rn BETWEEN 4 AND 6 --순위가 4 ~ 6 사이
ORDER BY sal DESC;
* 서브쿼리를 통해 얻은 결과에 ROWNUM을 다시 부여하여 새로운 테이블인 것처럼 사용
- 해결 2: 윈도우 함수의 RANK 사용
SELECT *
FROM (SELECT emp.*
RANK() OVER(ORDER BY sal DESC) AS rn --RANK 사용
FROM emp) A
WHERE rn BETWEEN 4 AND 6
ORDER BY sal DESC;
04. FETCH 절
- 출력될 행의 수를 제한하는 절
- ORACLE 12C이상부터 제공 (이전 버전: ROWNUM 사용)
- ORDER BY절 뒤에 사용(내부 파싱 순서도 ORDER BY 뒤)
- 문법
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
OFFSET N { ROW | ROWS }
FETCH { FIRST | NEXT } N { ROW | ROWS } ONLY;
- OFFSET: 건너뛸 행의 수
- N: 출력할 행의 수
- FETCH: 출력할 행의 수를 전달하는 구문
- FIRST: (OFFSET을 사용하지 않았을 경우) 처음부터 N행 출력 명령
- NEXT: (OFFSET을 사용했을 경우) 제외한 행 다음부터 N행 출력 명령
- ROW | ROWS: 행의 수에 따라 하나일 경우 단수 | 여러 값이면 복수형(구분하지 않아도 가능)
- 예제
SELECT empno, ename, job, sal
FROM emp
ORDER BY sal DESC
FETCH --출력할 행의 수를 전달하는 구문
FIRST --OFFSET 없음 -> 처음부터 출력
5 --N: 출력할 행의 수
ROWS --행의 수가 여러개: ROWS
ONLY; --emp에서 sal 순서대로 상위 5명
SELECT empno, ename, job, sal
FROM emp
ORDER BY sal DESC
OFFSET 3 ROW --OFFSET 사용: N(3)만큼 건너 뜀
FETCH --출력할 행의 수를 전달
FIRST --3 다음부터, 4부터 출력
2 --N: 2개
ROW ONLY; --emp 테이블에서 급여가 높은 순서대로 4~5번째 해당하는 직원 정보 출력
05. TOP N 쿼리
- SQL Sever에서 상위 N개 행 추출 문법
- 서브쿼리 사용 없이 하나의 쿼리로 정렬된 순서대로 상위 N개 추출 가능
- WITH TIES: 동순위까지 함께 출력 가능
- 문법
SELECT TOP N 컬럼1, 컬럼2
FROM 테이블명
ORDER BY 정렬컬럼명 [ASC | DESC];
- 예시
SELECT TOP 2 ename, sal
FROM emp
ORDER BY sal DESC; --emp 테이블의 상위 급여자 2명 출력(SQL Server)
SELECT TOP 2 WITH TIES ename, sal
FROM emp
ORDER BY sal DESC; --동순위 행도 함께 출력
- TOP은 동순위여도 개수(N)를 기준으로 출력, WITH TIES를 이용하면 동순위 행 모두를 출력할 수 있음
'SQL' 카테고리의 다른 글
[SQL] 윈도우 함수 (Window Function) (0) | 2025.02.26 |
---|---|
[SQL] 그룹 함수 (0) | 2025.02.17 |
[SQL] 집합 연산자 (0) | 2025.02.17 |
[SQL] 서브쿼리 (0) | 2025.02.17 |
[SQL] JOIN (2) (0) | 2025.02.17 |