Database/Oracle

Oracle 중복되는 데이터에는 같은 숫자 주며 순서 맥이기 . 윈도우 함수 DENSE_RANK()

Shane_Park 2021. 6. 3. 12:50
반응형

json 에서 issue 들을 받아오는 페이지가 있습니다.

 

 

아직 페이징 처리가 되지 않고 있기 때문에 데이터가 많은데요 위에서 보이는 것 처럼 Collection 들을 가지고 있다 보니 쿼리 결과문에서 겹치는 부분이 꽤 있습니다.

페이징을 위해 rownum 을 보통 먹이곤 했는데, 

rownum을 줬다가는 같은 PK를 가진 친구들도 각기 다른 rownum을 가지기 때문에 제대로 된 페이징 처리가 될 수 없습니다.

 

이럴때는, 오라클의 윈도우 함수를 이용해서 번호를 주면 됩니다.

일단 기존의 쿼리문과 결과문입니다.

select  rownum as rn,a.*
from (
    SELECT 
        ISSUE.ISSUE_SID AS ISSUE_ID ,ISSUE_NO ,ISSUE.PROJ_NO ,ISSUE_TITLE 
        ,ISSUE_CREATE_DATE ,ISSUE_START_DATE ,ISSUE_END_DATE ,ISSUE_STATUS
        ,ISSUE_PRIORITY ,PROGRESS
        ,MILESTONE.MILEST_SID, milestone.milest_title AS MILEST_TITLE
        ,WRITER.MEM_NO AS writer_no, writer.mem_pic_file_name AS writer_pic
        ,label.label_no, label.label_nm
        ,ASSIGNEE.mem_no, assignee.mem_pic_file_name
        ,(select count(*) -1
            from issue_history
            where issue_history.issue_sid = ISSUE.issue_sid
                    and issue_history.issue_his_type = 'RE'
        ) as replyCount
    FROM ISSUE
        LEFT OUTER JOIN MILESTONE ON (ISSUE.MILEST_SID = milestone.milest_sid)
        INNER JOIN MEMBER WRITER ON (ISSUE.MEM_NO = WRITER.MEM_NO)
        LEFT OUTER JOIN LABEL ON (issue.label_no = label.label_no)
        LEFT OUTER JOIN issue_assignee ON (issue.issue_sid = issue_assignee.issue_sid)
        LEFT OUTER JOIN MEMBER ASSIGNEE ON (issue_assignee.mem_no = assignee.mem_no)
    WHERE ISSUE.proj_no = 1
            and issue_status = 0 
    order by issue_no desc) a;

위에서  보이는 것 처럼, 같은 ID 를 가지고 있는 번호들도 각기 다른 RN 을 가지기 때문에

해당 번호를 이용해서 페이징 처리를 했다가는 문제가 생기게 됩니다.

 

이번엔 window 함수의 DENSE_RANK를 활용해 본 쿼리와 결과입니다.

select  a.*
from (
    SELECT dense_rank() over(order by issue.issue_sid desc) as dr
        ,ISSUE.ISSUE_SID AS ISSUE_ID ,ISSUE_NO ,ISSUE.PROJ_NO ,ISSUE_TITLE 
        ,ISSUE_CREATE_DATE ,ISSUE_START_DATE ,ISSUE_END_DATE ,ISSUE_STATUS
        ,ISSUE_PRIORITY ,PROGRESS
        ,MILESTONE.MILEST_SID, milestone.milest_title AS MILEST_TITLE
        ,WRITER.MEM_NO AS writer_no, writer.mem_pic_file_name AS writer_pic
        ,label.label_no, label.label_nm
        ,ASSIGNEE.mem_no, assignee.mem_pic_file_name
        ,(select count(*) -1
            from issue_history
            where issue_history.issue_sid = ISSUE.issue_sid
                    and issue_history.issue_his_type = 'RE'
        ) as replyCount
    FROM ISSUE
        LEFT OUTER JOIN MILESTONE ON (ISSUE.MILEST_SID = milestone.milest_sid)
        INNER JOIN MEMBER WRITER ON (ISSUE.MEM_NO = WRITER.MEM_NO)
        LEFT OUTER JOIN LABEL ON (issue.label_no = label.label_no)
        LEFT OUTER JOIN issue_assignee ON (issue.issue_sid = issue_assignee.issue_sid)
        LEFT OUTER JOIN MEMBER ASSIGNEE ON (issue_assignee.mem_no = assignee.mem_no)
    WHERE ISSUE.proj_no = 1
            and issue_status = 0) a;

 

위에서 보이듯 dense_rank() 를 사용해, issue_sid 로 정렬 했습니다.

이제 페이징에 사용 할 수 있는 근사한 번호가 생겼습니다.

이상입니다.

반응형