IT/Database

[PostgreSQL] 페이징 쿼리 작성하기

JJo 2018. 12. 16. 18:42

게시판이나 안드로이드에서 한번에 보여줄 수 있는 데이터는 한정적이기 때문에(물론..보여줄순있다)

사용자가 지정한 정렬조건으로 일부데이터만 보여주고 필요에 의해서 이후 데이터를 보여주는 방식을 많이 사용한다.


그러기 위해서는 필요한 데이터만 효율적으로 보여줘야 하는데

이 때, 페이징쿼리를 작성한다.




Query



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
SELECT 
    END_PAGE,
    CAFE_ID,
    CAFE_NM,
    CAFE_IMG_NM,
    CAFE_IMG_DIR,
    PRICE,
    LUNCH_YN,
    DINNER_YN,
    OPER_TIME,
    BUILD_ADDR,
    BUILD_NM,
    BUILD_TEL,
    BUILD_HOME,
    BUILD_KEY,
    BUILD_X,
    BUILD_Y,
    COALESCE(BUILD_SCORE,0) AS BUILD_SCORE,
    ROUND(CAST(DISTANCE AS NUMERIC),0) AS DISTANCE,
    USE_YN,
    INS_USER_DTM,
    UPD_USER_DTM
FROM(                                                             
    SELECT 
        (CASE WHEN 1 * 10 < COUNT(*) OVER() THEN 'FALSE' 
             WHEN 1 * 10 >= COUNT(*) OVER() THEN 'TRUE' END) AS END_PAGE,
        CAFE_ID,
        CAFE_NM,
        CAFE_IMG_NM,
        CAFE_IMG_DIR,
        PRICE,
        LUNCH_YN,
        DINNER_YN,
        OPER_TIME,
        BUILD_ADDR,
        BUILD_NM,
        BUILD_TEL,
        BUILD_HOME,
        BUILD_KEY,
        BUILD_X,
        BUILD_Y,
        (SELECT ROUND(AVG( COMMENT_SCORE),1FROM PUBLIC.CAFE_COMMENT WHERE CAFE_ID=CAFE.CAFE_ID GROUP BY CAFE_ID) AS BUILD_SCORE,
        (select earth_distance(ll_to_earth(37.483422126.891111), ll_to_earth(CAFE.BUILD_X,CAFE.BUILD_Y))) AS DISTANCE,
        USE_YN,
        INS_USER_DTM,
        UPD_USER_DTM
    FROM PUBLIC.CAFE AS CAFE
    ORDER BY DISTANCE ASC
    LIMIT 10 OFFSET (1 - 1* 10
) CAFE    
cs


48 line : Distance 거리별로 정렬 

49 line : 10row를 가지고 오는데 0번째부터 9번째까지 10row를 가지고온다

25~26 line : 현재까지 가지고 온 데이터가 끝인지 아니면 더 가지고 올 데이터가 있는지 판별하는 변수




생각해 볼 부분



SQLP자격증을 준비하면서 정말 많이 공부했었던 페이징처리 쿼리

실제로 적용한적은 없었는데 이번에 작은 프로젝트를 진행하면서 적용해봤다.


위 쿼리에서 핵심은

가장 안쪽 인라인뷰에서 Order by를 하고 

정렬된 상태에서의 LIMIT 10 OFFSET (1 - 1) * 10 을 통해

필요한 부분을 가지고 오는 것이다.


또, END_PAGE컬럼은 현재 20~30번째 데이터를 가지고 온다고 할 때

지금까지 30번째 로우 데이터를 가지고 왔을텐데

COUNT(*) OVER()을 통해 총 로우 수 보다 크거나같은지 혹은 작은지를 비교해

데이터가 더 있는지 판별하는 부분이 핵심이다.


페이징처리를 하는데 있어서

DB마다 문법이 조금씩 다르기 때문에

어떻게 적용하는지 확인을 배봐야 한다.

Oracle이라면 rownum을 이용히고

Sqlserver면 TOP을 이용하고..


위 쿼리는 안드로이드 리스트뷰에 적용하려고 작성한 쿼리이지만

이 기본적인 방법을 활용해서

웹에 게시판이라던지 활용할 수 있는 방법이 많다