본문 바로가기

카테고리 없음

페이징 처리

 SELECT USER_ID, USER_NAME, TOT_CNT
FROM   (
    SELECT  ROWNUM AS RN, USER_ID, USER_NAME,
                 COUNT(USER_ID) OVER() AS TOT_CNT
    FROM    (
        SELECT     USER_ID, USER_NAME
        FROM        USER_INFO
        WHERE      USER_NAME LIKE '김%'
        ORDER BY  USER_NAME
        )
    )
WHERE   RN BETWEEN 1 AND 10

저는 보통 페이징 처리할 때 이런식으로 쿼리를 작성합니다.

먼저 페이징 처리할 쿼리를 만든 후 밖에서 ROWNUM을 이용해서 행별로 번호를 부여한 후 그 밖에서 다시 행번호를 조건으로 하는거죠.
이때 당연하지만 중요한 몇가지....
-1-
ORDER BY 는 가장 안쪽(ROWNUM보다 먼저)에서 실행해야합니다.
ORDER BY를 ROWNUM과 동일하거나 하위에 하는 경우 당연히 원하는 순서에 맞게 행번호가 부여되지 않습니다.
-2-
COUNT(USER_ID) OVER() AS TOT_CNT
이건 전체 검색된(페이징 전) 행의 갯수입니다.
이걸 자바단에서 별도의 쿼리로 날리는 것도 하나의 방법입니다.
사실 불필요한 테이터를 db connection에 요청하게 되는 꼴입니다만, 이 한 데이터를 위해 다시 connection을 맺는 것도 거시기하죠. ㅡ0ㅡ;
이건 취향에 맞게 하시면 될겁니다.

덤)
OVER()란, GROUP BY와 유사하지만 정반대라고 보시면 됩니다.
GROUP BY는 데이터 전역을 그룹단위로 묶는데....
OVER()는 묶어야만 산출 가능한 데이터(GROUP BY로 해야 얻는 결과)를 도출해냅니다.
위에 예시를 보시면 대충 감이 오시겠죠. ㅎ
COUNT(USER_ID) OVER() AS TOT_CNT  
라고 하는 경우는 전체에서 USER_ID 를 COUNT 하게 되구요.

GROUP BY 역활을 넣을 수도 있습니다.
 COUNT(USER_ID) OVER(PARTITION BY USER_NAME) AS SAME_USER_NAME
이렇게 해주면,
SELECT COUNT(USER_ID)
FROM USER_INFO
GROUP BY USER_NAME
처럼 됩니다. ^^