Self Join 관련하여 문의 드리겠습니다. 0 4 2,915

by 똥쟁이찰스 [Oracle 기초] Self Join [2012.12.13 16:07:54]


안녕하세요.

오라클클럽에서 항상 많은 도움을 받고 있네요. 감사합니다.

질문이 하나 있어서 문의 드리겠습니다.

제 머리로는 좋은 해결법이 안나오네요..^^;

간단히 쿼리문을 먼저 보여드릴께요.(일 부분 입니다.)


SELECT IP
   , CASE WHEN (SELECT COUNT(*)
          FROM TABLE_1 B
          WHERE B.DATE > A.DATE
           AND B.IP = A.IP) > 0 THEN '0'
      ELSE '1'
      END CHK_IP
 FROM TABLE_1 A

음.. 이해가 가실지 모르겠네요.

먼저 원래 쿼리의 일 부분이라는 걸 말씀드리며

설명을 드리자면 해당 IP가 이전에 접속을 했었는지 확인을 해서 값을 '1' 또는 '0'으로 INSERT를 합니다.

위에 방법과 같이 하면 결과는 나오지만 데이터가 많을 경우 속도가 많이 느려 지더라구요.

해당 테이블에는 적지 않은 데이터가 들어 있습니다. 약 2천만건정도 입니다. 앞으로도 계속 증가를 합니다.

위에 내용에서 해당 날짜 보다 이전에 한번이라도 들어왔는지만 체크를 하면 되는데 지금과 같은 방법은

이전 데이터를 계속해서 조회를 하게 되어 있습니다. 그래서 시간적으로 많이 소요가 되는 것으로 보입니다.

제 머리에서는 방법이 안 나오네요....

어떠한 방법으로 해결을 하면 좋을 지 도움 요청 드립니다.^^
by 마농 [2012.12.13 16:20:11]
-- 이전 접속기록 체크라면 부등호가 뒤바뀐 듯 하구요.
-- (b.date > a.date) 을 (b.date < a.date) 로 바꾸시고
-- 단순 있는지 없는지, 존재여부만 체크한다면?
-- 전체 Count 할필요 없이 1건만 체크하면 됩니다.
-- (ROWNUM = 1) 조건 추가
-- (ip, date)로 구성된 인덱스가 있어야만 합니다.
SELECT ip
     , (SELECT NVL(MAX(0), 1)
          FROM table_1 b
         WHERE b.date < a.date
           AND b.ip = a.ip
           AND ROWNUM = 1
        ) chk_ip
  FROM table_1 a
;

by 마농 [2012.12.13 16:27:31]
-- 음... 다시 생각해보니
-- 서브쿼리로 존재여부 체크하는 방식은 작은테이블에서 큰테이블 체크할때나 쓰이는 방법이구요.
-- 같은 테이블이라면 굳이 위와 같이 할 필요가 없네요.
-- 분석함수를 이용하시면 됩니다.
SELECT ip
     , DECODE(LAG(ip) OVER(PARTITION BY ip ORDER BY date), '', 1, 0) chk_ip
  FROM table_1
;

by 똥쟁이찰스 [2012.12.13 16:52:49]
마농님 감사합니다..^^

쥐어 짜내도 안 나왔는데..

공부 열심히 해야겠네요..^^

마농님 덕분에 아주 쉽게 처리 했네요.. 너무 감사합니다~!^^

좋은 하루 보내세요^^

by 만세 [2012.12.13 16:54:49]
--이런 방법은 어떤가요?
SELECT IP
 , CASE WHEN EXISTS(SELECT 'X'
 FROM TABLE_1 B
 WHERE B.DATE > A.DATE
 AND B.IP = A.IP) THEN '0'
 ELSE '1' END CHK_IP
FROM TABLE_1 A;
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입