[Oracle] 오라클 #19, 의사컬럼(ROWNUM) 사용법

의사컬럼, Pseudo Column

rownum

- 진짜 컬럼이 아닌데 컬럼처럼 행동하는 요소

- 행번호 의사컬럼(현재행의 순서를 반환 의사컬럼)

- 오라클 전용.

- 서브쿼리를 잘하면 사용하기 쉬움


다음과 같은 결과가 나오는 테이블이 있다고 할때...

select * from tblInsa;

여기  << 지금 여기있는 빈 컬럼이 rownum 같은 역할을 하는 녀석입니다. 이녀석은 컬럼리스트에 rownum이라고 쓰면 컬럼으로써 역할을 할 수 있지만 기재하지 않으면 단지 몇번째 컬럼이라고만 보여주는 인덱싱역할 입니다.


그럼 rownum을 써볼까요??

select a.*,rownum from tblInsa a ;

맨 끝의 컬럼에 rownum이 나타나는 것을 볼 수 있습니다. 제일 왼쪽에 있는 인덱싱 번호랑 일치하는 것 보이시나요??


select name, buseo, jikwi,basicpay,rownum 

    from tblInsa order by basicpay desc;


>> 다음과 같이 정렬조건이 붙게되면 rownum의 순서가 깨지게 됩니다. 기존 select * from tblinsa 결과에서 정해진 rownum들이 order by 정렬조건에 의해서 다 깨어지는 것이지요.


그래서 다음과 같이 처리하게 됩니다. 새로운 order by 절에 알맞도록 rownum을 조정하는 작업입니다.


select name,buseo, jikwi,basicpay,rownum,rnum from 

    (select name, buseo, jikwi,basicpay,rownum as rnum

        from tblInsa 

            order by basicpay desc);


>> rownum은 from절이 실행될때 새로 만들어지게 됩니다. 즉, tblinsa에서 만들어진 rownum은 rnum으로(사실 별 의미없음), 바깥쪽 select 컬럼리스트에 다시 rownum을 써주면 order by절의 정렬순서를 가진 rownum이 탄생하게 됩니다.


rownum으로 값을 가져올수도 있지만 가져올 수 없는 경우도 있습니다.


select name, buseo, jikwi,basicpay,rownum

        from tblInsa

--            where rownum =1;      --O

--              where rownum <=5;  --O          

-------------------------------------------로우넘의 결과가 반드시 1이 포함되어야 한다.

--            where rownum =3; --X

--            where rownum >=10 and rownum<=20; --X

--            where rownum = 1; --X

--            where rownum >=1 and rownum<=5; --O

-------------------------------------------rownum은 조건에 사용하려면 반드시 1부터시작해서 연속적으로 값을 사용할 때만 조건으로 가능하다.

--            where rownum =1 or rownum=2 or rownum=3; --O

--            where rownum =1 or rownum=3 or rownum=5; --X

            where rownum =1 or rownum=2 or rownum=4; --얘는 1과 2만 가져오고 4는 못가져옴(왜냐하면 3이 끊겼기 때문)


무언가 페이징을 하려고 할때!

select t.*,rownum from 테이블 t where rownum between 5 and 10; 이렇게 하면 안된다는 뜻입니다. 

그렇다면 과연 어떤식으로 rownum을 통해서 페이징(between)을 할 수 있을까?


select name,basicpay,rownum as 방금만든행번호, rnum as 아까만든행번호

from (select name,basicpay,rownum as rnum

    from (select name,basicpay

          from tblInsa 

          order by basicpay desc))

    where rnum between 11 and 16;



>> 총 2번의 서브쿼리를 이용하는 방법으로 했습니다.(더 좋은 방법이 있겠지만 최대한 rownum을 살리는 방법으로 하다보니까...) 정렬조건을 가진 rownum을 저장하고 그 select 문을 감싼 select 문에서 rnum으로 선언해주면서 정렬 조건을 가진 rownum을 얻어낸느 방법입니다. 여기서 방금만든 행번호는 전체 select가 생성될때 생성되는 것이므로 연속되는 숫자가 아니면 sorting하는데 의미가 없는 컬럼입니다. rnum으로 between절 쓰셔야 합니다.


댓글

Designed by JB FACTORY