select /*+ index(user_info 인덱스명) */ * from user_info where user_score <= 회원a의 스코어 and user_no <> 'a' and rownum <= 10 union all select /*+ index(user_info 인덱스명) */ * from user_info where user_score >= 회원a의 스코어 and user_no <> 'a' and rownum <= 10
-- 순위까지 나타내야 한다면? 전체범위 처리를 할수밖에 없습니다. -- 점수가 동일하여 순위가 동일 할 수 있으므로 -- rownum_number 정렬항목에 유니크한 user_no 를 포함시켰습니다. WITH tmp AS ( SELECT user_no, user_id, user_score , RANK() OVER(ORDER BY user_score DESC) rk , ROW_NUMBER() OVER(ORDER BY user_score DESC, user_no) rn FROM user_info ) SELECT a.* FROM tmp a , (SELECT * FROM tmp WHERE user_no = 'a') b WHERE a.rn BETWEEN b.rn - 10 AND b.rn + 10 ORDER BY rn ;
-- 부분범위 처리를 위해서는 비니부장님 방법으로 하시면 되는데... -- 점수만으로는 유니크 하지 않기 때문에 이부분에 대한 추가 처리가 필요합니다. -- 유니크하게 비교하기 위해 ROWID 를 이용하겠습니다. -- 점수에 대한 인덱스명을 idx_score 라고 가정하겠습니다. WITH tmp AS ( -- 유저 a 의 정보를 pk 인덱스로 조회합니다. SELECT user_no, user_score, ROWID rid FROM user_info WHERE user_no = 'a' ) -- 인덱스 역순으로 a 를 포함하여 11건 가져오기. SELECT /*+ ORDERED USE_NL(b) INDEX_DESC(b idx_score) */ b.* FROM tmp a , user_info b WHERE b.user_score <= a.user_score AND b.ROWID <= DECODE(a.user_score, b.user_score, a.rid, b.ROWID) AND ROWNUM <= 11 UNION ALL -- 인덱스 순으로 a 를 제외하여 10건 가져오기. SELECT /*+ ORDERED USE_NL(b) INDEX_ASC(b idx_score) */ b.* FROM tmp a , user_info b WHERE b.user_score >= a.user_score AND b.ROWID >= DECODE(a.user_score, b.user_score, a.rid, b.ROWID) AND b.user_no != a.user_no AND ROWNUM <= 10 ;