++ 페이징을 구현할 때, ORACLE을 사용하면 ROWNUM을 사용한다.
조회 순번을 매기는 방법에는 두 가지가 있다.
1. ROWNUM
2. ROW_NUMBER()
1. ROWNUM
- 조회된 순서대로 순번을 매긴다.
- 또한, 쿼리로 반환되는 ROW의 갯수를 제한할 때도 사용 가능하다. (WHERE 절의 사용으로)
형식)
SELECT ROWNUM, 컬럼명
FROM 테이블명
*주의할 점
1) 만약, ROWNUM을 사용할때 동시에 ORDER BY를 사용하려고 한다면, 주의해야한다.
ORDER BY를 ROWNUM과 같은 위치에 사용한다면 ROWNUM이 적용된 다음에 정렬을 하기 때문에 순번이 뒤섞여버린다. 따라서 ORDER BY를 사용하고자 한다면 꼭 서브쿼리를 사용해서 정렬된 서브쿼리 결과에 ROWNUM을 사용해야한다.
## ORDER BY를 ROWNUM과 같은 위치에 사용할때 << 잘못된 쿼리. 순서가 뒤죽박죽이 된다.
SELECT * FROM employees ORDER BY employee_id WHERE ROWNUM < 11; // 잘못된 쿼리!
## 서브쿼리에 ORDER BY사용하고 탑레벨에 ROWNUM 사용
SELECT *
FROM
(SELECT * FROM employees ORDER BY employee_id)
WHERE ROWNUM < 11;
2) 양의 정수 1보다 큰 ROWNUM 테스트 조건은 항상 거짓이다.
이유는 ROWNUM의 검색 결과의 첫번째로는 항상 ROWNUM 1이 되기 때문이다.
따라서, 아래의 쿼리문은 어떠한 ROW로도 리턴하지 않고 항상 false를 반환한다.
SELECT * FROM employees
WHERE ROWNUM > 1;
따라서, oracle에서는 ROWNUM을 사용하는 대신 ROW_NUMBER() 함수를 사용하여 행 순서를 부여하는 것이 더 안전하고 예측가능한 방법이라고 한다.
2. ROW_NUMBER()
- ROW_NUMBER() 은 분석함수로, 리턴된 각각의 ROW에 고유한 숫자를 할당한다. (1로 시작한다.)
- 구체적 범위에서 ROW_NUMBER를 검색하는 쿼리 내에서 ROW_NUMBER를 사용해 서브쿼리를 중첩하면, 내부 쿼리의 결과에서 ROW의 정확한 하위 부분을 조회할 수 있다.
- ROW_NUMBER() 사용 시에, PARTITION BY 는 선택이고, ORDER BY 는 필수이다.
- PARTITION BY 는 같은 값들을 묶어서 표현할 때 사용한다. 일반적으로 파티션을 친다고 생각하면 쉽다.
각 파티션은 1로 시작하고 같은 파티션에 속하는 ROW가 많을수록 높은 숫자를 가진다. (숫자 순위가 높다)
- ORDER BY를 사용하여 정렬할 때는 ROWNUM 보다 ROW_NUMBER()을 사용하는 것이 더 효과적이다.
형식 1) 나누고 싶은 곳에서 구역을 나누고 정렬해서 순서를 정할때
ROW_NUMBER() OVER (PARTITION BY [그룹으로 묶을 컬럼] ORDER BY [정렬할 컬럼]) AS 별칭
SELECT department_id, last_name, employee_id, ROW_NUMBER()
OVER (PARTITION BY department_id ORDER BY employee_id) AS emp_id
FROM employees;
DEPARTMENT_ID LAST_NAME EMPLOYEE_ID EMP_ID
------------- ------------------------- ----------- ----------
10 Whalen 200 1
20 Hartstein 201 1
20 Fay 202 2
30 Raphaely 114 1
30 Khoo 115 2
30 Baida 116 3
30 Tobias 117 4
30 Himuro 118 5
30 Colmenares 119 6
40 Mavris 203 1
형식 2) 원하는 컬럼에 대해 정렬만해서 순서를 정할때
ROW_NUMBER() OVER (ORDER BY [정렬할 컬럼]) AS 별칭
SELECT ROW_NUMBER() OVER(ORDER BY a.job) row_num, a*
FROM emp a
ORDER BY a.job;
SELECT last_name
FROM
(SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
WHERE R BETWEEN 51 and 100;
51~100번째 사이의 last_name만 조회하는 쿼리 >> MYSQL 의 limit 함수와 비슷하다.
+++
ROW_NUMBER() 사용 예시 >> [Lv.3 Oracle] 131123. 즐겨찾기가 가장 많은 식당 정보 출력하기
참고
- https://tychejin.tistory.com/201
- https://escapefromcoding.tistory.com/371
- https://gent.tistory.com/170
'DB > Oracle' 카테고리의 다른 글
[Oracle] 임시테이블 만들기 / WITH절 (0) | 2023.11.06 |
---|---|
[Oracle] SELECT 결과 상위 N개만 검색 / FETCH FIRST N ROWS ONLY (0) | 2023.11.05 |
[Oracle] 데이터 중복 제거 / DISTINCT, GROUP BY (0) | 2023.10.21 |
[Oracle] GROUP BY / HAVING 절 (0) | 2023.10.15 |
[Oracle] 반올림, 버림(절사) / ROUND 함수, TRUNC 함수 (0) | 2023.10.12 |