Search
Duplicate

Top N 쿼리

Top N 쿼리

💡
결과 집합에서 상위 N개의 행을 반환하는 쿼리

종류

ROWNUM
ROWID

ROWNUM

💡
SELECT 문의 논리적인 순번을 나타내는 가상의 컬럼
🕹 ORACLE DB
✅ 데이터를 출력할 때 부여되는 논리적인 순서 번호이기 때문에, ROWNUM 을 사용하여 페이징 처리를 하기 위해서는 인라인 뷰를 써야한다.
페이징 처리(Paging)란?
페이징 처리는 대량의 데이터를 한 번에 모두 조회하지 않고, 일정한 개수로 나누어 페이지 단위로 조회하는 기법입니다. 예를 들어, 게시판에 1,000개의 게시글이 있을 때 한 페이지에 10개씩 보여주면 총 100페이지가 생성됩니다.
페이징 처리의 주요 목적:
성능 향상: 필요한 데이터만 조회하여 DB 부하를 줄이고 응답 속도를 개선합니다.
사용자 경험 개선: 한 화면에 적절한 양의 데이터를 보여줌으로써 가독성과 편의성을 높입니다.
메모리 효율: 전체 데이터를 메모리에 로드하지 않아 서버 자원을 효율적으로 사용합니다.
Oracle에서는 ROWNUM을 활용하여 페이징 처리를 구현하며, 원하는 범위의 데이터만 추출할 수 있습니다.

⭐ ROWNUM 를 활용한 페이징 처리

SELECT * FROM ( SELECT ROWNUM AS row_num, no, title, content FROM board WHERE ROWNUM <= 10 -- 원하는 페이지 크기를 여기에 지정합니다. ) WHERE row_num >= 1; -- 원하는 페이지 번호에 맞게 시작하는 행 번호를 여기에 지정합니다.
SQL
복사

board 테이블 생성 및 샘플 데이터

-- DDL CREATE TABLE board ( no NUMBER NOT NULL, title varchar2(100) NOT NULL, writer varchar2(100) NOT NULL, content varchar2(1000), reg_date DATE DEFAULT sysdate NOT NULL, upd_date DATE DEFAULT sysdate NOT NULL, views NUMBER DEFAULT 0 NOT NULL, PRIMARY KEY (no) );
SQL
복사
-- 샘플 데이터 INTO board (title, writer, content) VALUES ('제목 1', '작성자 1', '내용 1'); INTO board (title, writer, content) VALUES ('제목 2', '작성자 2', '내용 2'); INTO board (title, writer, content) VALUES ('제목 3', '작성자 3', '내용 3'); INTO board (title, writer, content) VALUES ('제목 4', '작성자 4', '내용 4'); INTO board (title, writer, content) VALUES ('제목 5', '작성자 5', '내용 5'); INTO board (title, writer, content) VALUES ('제목 6', '작성자 6', '내용 6'); INTO board (title, writer, content) VALUES ('제목 7', '작성자 7', '내용 7'); INTO board (title, writer, content) VALUES ('제목 8', '작성자 8', '내용 8'); INTO board (title, writer, content) VALUES ('제목 9', '작성자 9', '내용 9'); INTO board (title, writer, content) VALUES ('제목 10', '작성자 10', '내용 10'); INTO board (title, writer, content) VALUES ('제목 1', '작성자 1', '내용 1'); INTO board (title, writer, content) VALUES ('제목 2', '작성자 2', '내용 2'); INTO board (title, writer, content) VALUES ('제목 3', '작성자 3', '내용 3'); INTO board (title, writer, content) VALUES ('제목 4', '작성자 4', '내용 4'); INTO board (title, writer, content) VALUES ('제목 5', '작성자 5', '내용 5'); INTO board (title, writer, content) VALUES ('제목 6', '작성자 6', '내용 6'); INTO board (title, writer, content) VALUES ('제목 7', '작성자 7', '내용 7'); INTO board (title, writer, content) VALUES ('제목 8', '작성자 8', '내용 8'); INTO board (title, writer, content) VALUES ('제목 9', '작성자 9', '내용 9'); INTO board (title, writer, content) VALUES ('제목 10', '작성자 10', '내용 10'); INTO board (title, writer, content) VALUES ('제목 1', '작성자 1', '내용 1'); INTO board (title, writer, content) VALUES ('제목 2', '작성자 2', '내용 2'); INTO board (title, writer, content) VALUES ('제목 3', '작성자 3', '내용 3'); INTO board (title, writer, content) VALUES ('제목 4', '작성자 4', '내용 4'); INTO board (title, writer, content) VALUES ('제목 5', '작성자 5', '내용 5'); INTO board (title, writer, content) VALUES ('제목 6', '작성자 6', '내용 6'); INTO board (title, writer, content) VALUES ('제목 7', '작성자 7', '내용 7'); INTO board (title, writer, content) VALUES ('제목 8', '작성자 8', '내용 8'); INTO board (title, writer, content) VALUES ('제목 9', '작성자 9', '내용 9'); INTO board (title, writer, content) VALUES ('제목 10', '작성자 10', '내용 10'); INTO board (title, writer, content) VALUES ('제목 1', '작성자 1', '내용 1'); INTO board (title, writer, content) VALUES ('제목 2', '작성자 2', '내용 2'); INTO board (title, writer, content) VALUES ('제목 3', '작성자 3', '내용 3'); INTO board (title, writer, content) VALUES ('제목 4', '작성자 4', '내용 4'); INTO board (title, writer, content) VALUES ('제목 5', '작성자 5', '내용 5'); INTO board (title, writer, content) VALUES ('제목 6', '작성자 6', '내용 6'); INTO board (title, writer, content) VALUES ('제목 7', '작성자 7', '내용 7'); INTO board (title, writer, content) VALUES ('제목 8', '작성자 8', '내용 8'); INTO board (title, writer, content) VALUES ('제목 9', '작성자 9', '내용 9'); INTO board (title, writer, content) VALUES ('제목 10', '작성자 10', '내용 10'); INTO board (title, writer, content) VALUES ('제목 1', '작성자 1', '내용 1'); INTO board (title, writer, content) VALUES ('제목 2', '작성자 2', '내용 2'); INTO board (title, writer, content) VALUES ('제목 3', '작성자 3', '내용 3'); INTO board (title, writer, content) VALUES ('제목 4', '작성자 4', '내용 4'); INTO board (title, writer, content) VALUES ('제목 5', '작성자 5', '내용 5'); INTO board (title, writer, content) VALUES ('제목 6', '작성자 6', '내용 6'); INTO board (title, writer, content) VALUES ('제목 7', '작성자 7', '내용 7'); INTO board (title, writer, content) VALUES ('제목 8', '작성자 8', '내용 8'); INTO board (title, writer, content) VALUES ('제목 9', '작성자 9', '내용 9'); INTO board (title, writer, content) VALUES ('제목 10', '작성자 10', '내용 10');
SQL
복사

ROWID

💡
각 행을 고유하게 식별하는데 사용되는 식별자
구성 요소
설명
오브젝트 번호
ROWID가 속한 객체(테이블 또는 클러스터)의 고유한 번호를 나타냅니다.
상대 파일 번호
행이 저장된 상대적인 데이터 파일 번호를 나타냅니다.
블록 번호
행이 저장된 데이터 블록의 번호를 나타냅니다.
데이터 번호
블록 내에서의 행의 상대적인 위치를 나타냅니다.
ROWID 예시코드
SELECT ROWID , employee_id , first_name FROM employees WHERE department_id = 30;
SQL
복사

OFFSET

💡
조회 결과에서 지정한 행의 개수만큼 건너뛴 후 데이터를 조회할 때 사용하는 구문이다.
✅ Oracle 12c 이상에서 사용 가능

문법

SELECT 컬럼 FROM 테이블 ORDER BY 정렬컬럼 OFFSETindex ROWS FETCH NEXT 가져올_행수 ROWS ONLY;
SQL
복사
OFFSET
행 index (0~)
FETCH NEXT
가져올 행의 개수

예시

급여 1~10위
SELECT employee_id, last_name, salary FROM employees ORDER BY salary DESC OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
SQL
복사
➡ 급여가 높은 순서로 1위부터 10위까지 조회
페이징 처리
➡ 1페이지 (페이지당 10개씩) : 1행~10행
SELECT employee_id, last_name, salary FROM employees ORDER BY employee_id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
SQL
복사
➡ 2페이지 (페이지당 10개씩) : 11행~20행
SELECT employee_id, last_name, salary FROM employees ORDER BY employee_id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
SQL
복사

PERCENT

💡
PERCENT 키워드를 지정하면 행의 수가 아닌 퍼센트(비율)로 조회할 수 있다.
SELECT employee_id, last_name, salary FROM employees ORDER BY salary DESC FETCH FIRST 10 PERCENT ROWS ONLY;
SQL
복사
➡ 급여가 상위 10%인 사원을 조회
SELECT employee_id, last_name, salary FROM employees ORDER BY salary ASC FETCH FIRST 10 PERCENT ROWS ONLY;
SQL
복사
➡ 급여가 하위 10%인 사원을 조회