Q. select 결과물 중 맨 위의 5개만 출력해보고 싶으면 어떻게 해야 할까?
select 결과물 중 n번째부터 m개를 출력하고 싶다면?
ex) 게시판, 페이징,,
DBMS 마다 구현 방법 다름
MYSQL : LIMIT -> 제일 깔끔하게 나온다
MS SQL server : TOP
ORACLE : ROWNUM -> 제일 더럽게 나온다
rownum : select 시 oracle에서 붙여주는 행 번호
SELECT ROWNUM, empno, ename, sal FROM t_emp;
상위 5개만 출력하기
SELECT empno, ename, sal From t_emp
WHERE rownum <= 5
ORDER BY empno DESC;
* rownum은 select 이후에 시행된다
고로 select 이후에 order by를 하면 순서가 망가질 수 있다
이 테이블에서 기본키는 empno!
SELECT rownum, empno, ename, sal FROM t_emp
WHERE rownum <= 5
ORDER BY sal desc; -- 순서 엉망 pk 아닌걸로 ORDER BY 했을 때!
Q. order by 없을 때 무슨 순서대로 값이 정렬될까?
pk의 오름차순. pk가 인덱스로 설정되는데 그 pk의 오름차순 순서대로 나온다.
Q. rownum 범위가 1을 포함하지 않으면 안되나?
값이 나오지 않는다
rownum은 select 수행한 붙여진다
rownum <= 5 은 1-5 나온다는 보장이 있는데 rownum > 5는 몇번까지 나온다는 보장이 없으니 동작을 안하는 것 같다
그러면 상위 5개를 어떻게 뽑아낼 수 있을까?
SELECT rownum, empno, ename, sal
FROM t_emp
WHERE rownum > 5 -- 안된다 why?? 휴.. 응? 15:23
ORDER BY empno desc;
A. 6행부터 10행까지 출력 (2페이지) mysql은 나오나 oracle은 나온다 -> 해결방법 서브쿼리 사용!
첫번째 ) select문 생성
SELECT empno, ename, sal FROM t_emp ORDER BY empno DESC
두번째 ) from절에 넣기
* rownum에 별명을 붙여줘야 한다
SELECT rownum AS rnum, T.*
FROM (SELECT empno, ename, sal FROM t_emp ORDER BY empno DESC) T;
세번째 ) 위의 결과를 sub query에 넣을 것
* 이제부터 rownum은 일반적인 column이다. sub query의 결과물이다! 이상하게 꼬였던 rownum이 아니다!
SELECT * FROM
(
SELECT rownum AS rnum, t.* -- rnum 별명 붙여야 한다
FROM (SELECT empno, ename, sal FROM t_emp ORDER BY empno DESC) t;
)
;
네번째 ) 정렬해보자
* 완성! inline view와 rownum 활용!
SELECT * FROM
(
SELECT ROWNUM AS RNUM, T.*
FROM (SELECT empno, ename, sal FROM t_emp ORDER BY empno DESC) T
)
--WHERE RNUM >= 6 AND RNUM < 6 + 5 -- 2페이지
WHERE RNUM >= 11 AND RNUM < 11 + 5 -- 3페이지
;
row_number() over (order by 정렬 컬럼1, ... )
특정 column의 값을 기준으로 정렬한 뒤 순서를 매기기
사용법 : SELECT ROW_NUMBER() OVER (ORDER BY 정렬 컬럼, ... ), 서브쿼리컬럼 FROM 서브쿼리
* over 키워드가 같이 나와야 한다
sal 역순으로 한 값이 나온다
* sal 역순으로 한 다음에 rnum이 나온다. 이게 rownumber가 해주는 역할이다.
SELECT ROW_NUMBER() OVER (ORDER BY sal DESC) AS RNUM, T.*
FROM (SELECT empno, ename, sal FROM t_emp ORDER BY empno DESC) T
row_number() 는 '출력 순서'
rank() 는 '순위 통계' - 동일한 값은 동일한 rank로 1,2,2,4,5
SELECT ROW_NUMBER OVER(ORDER BY total DESC) "RNUM",
RANK() OVER(ORDER BY total DESC) "RANK",
T.*
FROM (SELECT s.name, e.total FROM t_student s, t_exam01 e
WHERE s.studno = e.studno
) T;
'database > Oracle' 카테고리의 다른 글
[Oracle] View (0) | 2022.09.04 |
---|---|
[Oracle] 집합연산자 set operator (0) | 2022.09.02 |
[Oracle] DML sub query (0) | 2022.09.02 |
[Oracle] 위치별 sub query (0) | 2022.09.02 |
[Oracle] 상호연관 sub query (0) | 2022.09.02 |