Skip to content

SQL ROWNUM #

Find similar titles

1회 업데이트 됨.

Edit
  • 최초 작성자
  • 최근 업데이트
    Dragon

ROWNUM #

정의 #

쿼리 내에서 사용 가능한(실제 칼럼이 아닌) 가상 칼럼이다. ROWNUM에는 숫자 1,2,3,4, ... 의 값이 할당된다. 여기서 n은 ROWNUM과 함께 상용하는 행의 수를 의미한다. ROWNUM의 값은 행에 영구적으로 할당되지 않는다. 테이블의 행은 숫자와 연계되어 참조될 수 없다. 따라서 테이블에서 row5를 요청할 수 없다. 왜냐하면 row5는 존재하지 않기 때문이다.

예제 #

ROWNUM 값은 쿼리의 조건절이 처리되고 난 후 그리고 sort, aggregation이 수행되기 전에 할당된다. 또한 ROWNUM 값은 할당된 이후에만 증가된다. 따라서 아래의 쿼리에서는 행을 반환하지 않는다.

select* from t where ROWNUM >1;

첫 번째 행에 대해 ROWNUM>1의 조건이 참이 아니기 때문에 ROWNUM은 2로 증가하지 않는다. 다시 아래로 생각해보자.

select....ROWNUM from t where group by having order by;

위의 쿼리는 아래와 같은 순서로 처리된다.

  1. FROM/WHERE 절이 먼저 처리된다.
  2. ROWNUM이 할당되고 FROM/WHERE 절에서 전달되는 각각의 출력 로우에 대해 증가(increment) 된다.
  3. SELECT가 적용된다.
  4. GROUP BY 조건이 적용된다.
  5. HAVING이 적용된다.
  6. ORDER BY 조건이 적용된다.

따라서 아래와 같은 쿼리는 에러가 발생한다.

select * from emp where ROWNUM <=5 order by sal desc;

이 쿼리는 가장 높으 연봉을 받는 다섯 명의 직원을 조회하기 위한 Top-N 쿼리로 작성되었다. 하지만 실제로 쿼리는 5개의 레코드를 랜덤하게 반환하게 되고 salary를 기준으로 정렬된다. 이 쿼리를 사용하기 위해서 사용되는 가상 코드는 아래와 같다.

ROWNUM = 1 for x in(select * from emp) loop exit when NOT(ROWNUM<=5)
OUTPUT record to tempROWNUM = ROWNUM+1 end loop SORT TEMP

위에서 볼 수 있듯 처음 5개의 레코드를 가져온 후 바로 sorting이 수행되며 쿼리에서 "WHERE ROWNUM=5"또는 "WHERE ROWNUM>5"와 같은 조건은 의미가 없다. 이는 ROWNUM 값이 조건자 실행 과정에서 행에 할당되며 행이 WHERE 조건에 의해 처리된 이후에만 증가되기 때문이다. 따라서 올바르게 처리된 쿼리는 아래와 같다.

select * from (select * from emp order by sal desc) where ROWNUM<=5;

위 쿼리는 salary를 기준으로 EMP를 내림차순으로 정렬 후 상위의 5개 레코드를(TOP-5 레코드)를 반환한다. 오라클 데이터베이스가 실제로 전체 결과 셋을 정렬하진 않는다.

예제2 #

아래와 같은 쿼리가 있다고 가정해보자.

select.... from .... where order by columns;

또 이 쿼리가 반환하는 데이터가 수천 ~ 수만 개 라고 가정해보자. 하지만 사용자가 실제로 관심 있는 것은 상위 특정 N 개의 결과 값이다. 이 결과를 얻기 위해서는 아래와 같은 방법이 있다.

클라이언트 어플리케이션에서 쿼리를 실행하고 상위 N 개의행만 가져오도록 명령 쿼리를 in-line view로 활용하고 ROWNUM을 이용하여 결과 셋을 제한하는 방법(ex : select * from (query..) where ROWNUM<=N)
0.0.1_20231010_1_v71