각각의 최근값? 구하기 (제목수정됨) 0 6 562

by 타핑이 [Oracle 기초] [2018.09.10 17:25:09]


GROUP_NO PK_DATE PK_SEQ AMOUNT

3015

20180907 3 3000
2003 20180906 2 2000
1005 20180909 7 4000
1005 20180907 9 3000
2003 20180907 1 1000
1005 20180909 6 3000
3015 20180907 4 4000
1005 20180908 33 1500
3015 20180905 27 200

실제 테이블에는 위와 같은 데이터가 2600만건 정도 있고, GROUP_NO도 제가 위에 적어놓은 3015,2003,1005 이외에도 수십개가 더 있긴 합니다. 제가 인터넷 되는 컴퓨터로 데이터를 옮기기가 너무 힘들어 수기로 적다보니... 많이 빠지긴 했습니다...

컬럼도 몇개 더 있는데 뽑을 데이터가 저거면 충분할거 같아 생략했습니다. ㅠ.ㅠ 

PK는 GROUP_NO, PK_DATE, PK_SEQ 세개입니다!

여기서 뽑아야될 데이터가 오늘(당일) 날짜 이전의 데이터 중에 가장 최신 데이터를 GROUP_NO당 하나 뽑는건데요.

SEQ는 높을수록 최신이고 DATE는 오늘에 가까울수록 최근이구요.

그래서 제가 짜본 쿼리가

SELECT *

  FROM (

         SELECT GROUP_NO

                  , PK_DATE

                  , PK_SEQ

                  , AMOUNT

                  , RANK() OVER(PARTITION BY GROUP_NO ORDER BY PK_DATE DESC, PK_SEQ DESC) RK

             FROM T

           WHERE PK_DATE < TO_DATE('20180910', 'YYYYMMDD')

               AND GROUP_NO IN ('3015','2003','1005')

  )

WHERE RK = 1

요렇게 뽑으니 나오긴 하는데... 테이블의 데이터가 이상하게 들어 있는지 1분이 넘게 걸리는 불상사가...=_=a

혹시 좀 나은 방법이 있을까 해서요....ㅠㅠ

by 우리집아찌 [2018.09.10 17:55:56]

인덱스가 어떻게 구성되어있는지 올려주세요.


by 우리집아찌 [2018.09.11 17:27:47]

PK가 적혀있었네요. ^^*


by 우리집아찌 [2018.09.10 18:00:54]

혹시 파티셔닝 테이블은 아닌가요?

파티셔닝 테이블이면 파티션 키도 알려주세요.


by 마농 [2018.09.10 18:08:17]

1. pk_date 컬럼의 자료형 확인하세요.
  - date 인지? varchar2 인지?
  - varchar2 라면 조건 잘못 준 듯 하고요
2. 실행계획 확인해 보세요.
  - inlist iterator 로 처리 범위를 줄여야 하고요.
  - window sort pushed rank 로 정렬을 효율적으로 해야 합니다.
  - index_desc 힌트를 통해 window nosort 를 유도해 보세요.
  - nosort 가 pushed rank 보다 효율적입니다.
  - 어차피 PK 라서 rank 를 써도 결과는 같지만. row_number 가 의미상 맞습니다.


by 타핑이 [2018.09.11 16:47:40]

제가 공부를 더 해야하나봅니다 후..

위에 만든 쿼리도 여기 구루비 사이트 열심히 보면서 그림밑에 대고 따라그리기 하듯 만들어서 힘들었는데...ㅠ

여러가지 답변이 있는데 모르는말이 너무 많네요... 답변 감사합니다!

주변에 한번 물어보고 해결해보겠습니다!


by 마농 [2018.09.11 17:14:18]
SELECT *
  FROM (SELECT /*+ INDEX_DESC(t pk_t) */
               group_no
             , pk_date
             , pk_seq
             , amount
             , ROW_NUMBER() OVER(PARTITION BY group_no ORDER BY pk_date DESC, pk_seq DESC) rn
          FROM t
         WHERE pk_date < TRUNC(sysdate)
           AND group_no IN ('3015', '2003', '1005')
        )
 WHERE rn = 1
;

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입