안녕하세요. 저번에 구루비 고수님께서 만들어주셨던 쿼리에서 페이징을 넣으려고 하는데요
SELECT A.RNUM
, A.CONTENTS_ID
, A.TITLE
, A.LANG_CD
, A.UPDATE_DATE
, A.COMP_TEXT
, A.COMP_TYPE
FROM (
SELECT CEIL ((ROW_NUMBER() OVER(ORDER BY B.UPDATE_DATE ASC)+0.00) / (10+0.00)) AS RNUM
, B.CONTENTS_ID
, B.TITLE
, B.DESCRIPTION
, B.LANG_CD
, B.UPDATE_DATE
, C.COMP_TEXT
, C.COMP_TYPE
, ROW_NUMBER() OVER(PARTITION BY B.CONTENTS_ID ORDER BY C.SORT_NO ASC) AS SORT_NO
FROM TB_CONTENTS B, TB_CONT_COMPONENT C
WHERE 1=1
AND B.CONTENTS_ID = C.CONTENTS_ID(+)
AND B.CONTENTS_TYPE = 'FOT'
AND B.USE_YN = 'Y'
AND B.DEL_YN = 'N'
AND B.POC_CD = 'NO'
AND B.LANG_CD = 'KO'
AND C.COMP_TYPE(+) = 'A3'
AND C.LANG_CD(+) = 'KO'
) A
WHERE 1=1
AND SORT_NO = 1
AND RNUM = 3
;
위 쿼리를 돌리면 아래 첫번째 사진처럼 RNUM이 3일때 정렬이 이상해지더라구요...
이유를 알수는 없었지만
AND B.LANG_CD = 'KO'
AND C.COMP_TYPE(+) = 'A3'
AND C.LANG_CD(+) = 'KO'
위 쿼리 밑에 다시한번
ORDER BY C.SORT_NO ASC
이렇게 주면 그때는 정상으로 나와서 이렇게 사용하다가
제가 역순으로 정렬을 해야 해서 오더바이를 DESC로 하니까
이상하게 정렬이 안되는겁니다...
ASC일때는 RNUM이 1일때 10개씩 보여줬거든요
SELECT CEIL ((ROW_NUMBER() OVER(ORDER BY B.UPDATE_DATE ASC)+0.00) / (10+0.00)) AS RNUM
여기서 10+0.00이 부분이 10개를 보여준다 이런 말인데
ASC일때는 아래 두번째 사진처럼 잘 보여주는데
DESC를 넣으면 첫페이지가 7개 두번째 페이지가 10개...마지막 페이지에 남은 리스트를 보여주는데요...
SELECT CEIL ((ROW_NUMBER() OVER(ORDER BY B.UPDATE_DATE DESC)+0.00) / (10+0.00)) AS RNUM
ORDER BY C.SORT_NO DESC
위처럼 저렇게 DESC로 변경하면 3번째 사진처럼 첫 페이지가 7개가 나오고 정렬이 안되는데 도저히...모르겠습니다...
그리고 SORT_NO = 1 이것도 마지막에 조건을 줘야 쿼리가 돌아가더라구요...저 서브쿼리안에 넣으면 오류가 납니다...하...
고수님들 도와주세요...
내부 sort_no을 기준으로 가져와야 하는 값이 있어서 id로 바꾸면 안되는거 같아요
바꾼다고 해도 desc할때 첫 페이지에 10개가 안나오고 7개만 나오는건 그대로 입니다...
정렬이 잘안되요...저는 DESC로 정렬해도 ASC처럼 정렬이 됐으면 하는 방법이 궁금합니다 ㅠ
CEIL 이부분에 정렬을 CEIL ((ROW_NUMBER() OVER(ORDER BY B.CONTENTS_ID DESC)+0.00) / (10+0.00)) AS RNUM
이런식으로 바꾸면 마지막 페이지 정렬이 이상합니다 최근거 하나랑 나머지 마지막 리스트 이렇게 이상하게 나와요...
하....왜 그럴까요...
CEIL ((ROW_NUMBER() OVER(ORDER BY B.CONTENTS_ID DESC)+0.00) / (10+0.00)) AS RNUM
여기 UPDATE_DATE에서 CONTENTS_ID이걸로 바꿨습니다.
ROW_NUMBER() OVER(PARTITION BY B.CONTENTS_ID ORDER BY C.SORT_NO ASC) AS SORT_NO
여기서 C.SORT_NO ASC 이거는 SORT_NO에서 낮은거 하나를 가져오고 싶어서 이렇게 했는데 맞는건지 모르겠네요...
AND SORT_NO = 1
AND RNUM = 1
이렇게 주면 안된다고 하셔서 서브쿼리에 둘다 하나씩 넣어봤는데
둘다 안되더라구요...그래서 마지막에 줄수밖에 없는데 서브쿼리로 또 감싸야...하나요...................
너무 복잡해서 머리가 터질 거 같습니다 ㅋ;;
1. 네. 서브쿼리로 또 감싸야 합니다.
2. +0.00 은 불필요해 보이네요.
SELECT * FROM (SELECT CEIL(ROW_NUMBER() OVER(ORDER BY a.contents_id DESC) / 10) rnum , a.contents_id , a.title , a.lang_cd , a.update_date , a.comp_text , a.comp_type FROM (SELECT b.contents_id , b.title , b.description , b.lang_cd , b.update_date , c.comp_text , c.comp_type , ROW_NUMBER() OVER(PARTITION BY b.contents_id ORDER BY c.sort_no) sort_no FROM tb_contents b , tb_cont_component c WHERE 1=1 AND b.contents_id = c.contents_id(+) AND b.contents_type = 'FOT' AND b.use_yn = 'Y' AND b.del_yn = 'N' AND b.poc_cd = 'NO' AND b.lang_cd = 'KO' AND c.comp_type(+) = 'A3' AND c.lang_cd (+) = 'KO' ORDER BY b.update_date, b.contents_id ) a WHERE sort_no = 1 ) a WHERE rnum = 3 ;
페이징 쿼리의 장점을 살리지 못하는 쿼리입니다.
CEIL 로 인해 ROW_NUMBER 의 STOP 기능을 효율적으로 이용 할 수 없고
sort_no 로직은 전체범위 처리를 하게 됩니다.
우선 메인 테이블만으로 페이징 처리를 최적화 하고
comp_text 는 10건에 대해서만 조인하여 가져오는 방식이 좋습니다.
comp_type 은 어차피 조건 주고 가져오는 부분이라 굳이 select list 에 넣을 필요 없어 보이네요.
SELECT CEIL(rn / 10) rnum , contents_id , title , description , lang_cd , update_date , (SELECT MIN(comp_text) KEEP(DENSE_RANK FIRST ORDER BY sort_no) FROM tb_cont_component c WHERE c.contents_id = b.contents_id AND c.comp_type = 'A3' AND c.lang_cd = 'KO' ) comp_text FROM (SELECT ROW_NUMBER() OVER(ORDER BY contents_id DESC) rn , contents_id , title , description , lang_cd , update_date FROM tb_contents WHERE 1=1 AND contents_type = 'FOT' AND use_yn = 'Y' AND del_yn = 'N' AND poc_cd = 'NO' AND lang_cd = 'KO' ) b WHERE rn >= 10 * (3 - 1) + 1 AND rn <= 10 * 3 ;