특정기준 추출 후 삭제하고 원장에서 추출한 결과 다시 중복제거하기 반복 0 7 1,070

by 타잔 [Oracle 기초] [2017.11.24 15:59:08]


안녕하세요.
며칠을 아무리 해봐도 안되서 도움을 요청드립니다.

1.테이블 구조

< 원본 테이블 = X > RANK는 숫자형
여기서 RANK는 CD1의 특정 값을 가지고 부여한 것입니다

CD1 CD2 RANK
A1 A2 1
A1 A3 1
A2 A1 2
A2 A4 2
A2 A5 2
A3 A1 3
A3 A5 3
A4 A2 3
A5 A3 4
A5 A4 4
A5 A6 4
A5 A3 4


2.결과테이블 생성방법

[STEP1]
- 위의 원본 테이블 X 테이블에서 RANK = 1인 행을 모두 추출 = Y1
- 원본 테이블 X에서 RANK = 1인 행을 모두 삭제 
- Y1테이블을 임시테이블로 저장하여 원본 테이블 X의 CD2와 Y1테이블의 CD2가 존재하는 경우 삭제

STEP1 결과 

Y1테이블                                         X 테이블
                                                    (RANK = 1을 삭제하고 Y1의 CD2 값이 X의 CD2에 존재하는 경우 삭제)

CD1 CD2 RANK   CD1 CD2 RANK
A1 A2 1   A2 A1 2
A1 A3 1   A2 A4 2
        A3 A5 3
        A3 A1 3
        A3 A5 3
        A5 A4 4
        A5 A6 4

[STEP2]
- RANK = 2인 행을 모두 추출 = Y2
- 원본 테이블 X에서 RANK = 2인 행을 모두 삭제 
- Y2 테이블을 임시테이블로 저장하여  원본 테이블 X에서 Y2테이블의 CD2 중복을 제거 후 Y1테이블과 통합(UNION ALL)

STEP2 결과

Y2테이블                                        X 테이블

CD1 CD2 RANK   CD1 CD2 RANK
A2 A1 2   A3 A5 3
A2 A4 2   A3 A5 3
        A5 A6 4

Y1, Y2 통합한 테이블(Z)
새로 생성: Z - 최종 테이블의 모습으로 RANK = 3, 4 계속 쌓이는 것입니다.

CD1 CD2 RANK
A1 A2 1
A1 A3 1
A2 A1 2
A2 A4 2

.
.
.
[STEP10000]
이런식으로 대략 1만번 수행해야 합니다.
RANK 가 1만 몇번까지 있어서요.

아니면 다른 방법이 있을것도 같습니다.

by 마농 [2017.11.24 17:24:56]

step1 의 결과(남은 X)를 보여주셨네요.
step2 의 결과(?)는 어디 있나요?
"Y1테이블과 통합"하는 대상이 뭔가요?
그래서 최종 결과가 어떻게 나와야 하나요?
또 최종 결과가 어떤 형태로 나와야 하나요?
남아있는 X 가 최종 결과인가요?
아니면? Y1 ? 아니면???


by 타잔 [2017.11.24 18:05:15]

질문 수정했습니다.
Y1은 새로이 생성되는 Y2와 통합하고요
통합테이블은 Z로 최종 테이블입니다.


by 마농 [2017.11.24 18:14:57]

왜? rank2 인 A5 가 y2 가 아닌 x 에 남아 있죠?
단순 cd2 로 중복 제거하고 가장 rank 가 작은 걸 가져오면 되겟는데요?

WITH t AS
(
SELECT 'A1' cd1, 'A2' cd2, 1 rank FROM dual
UNION ALL SELECT 'A1', 'A3', 1 FROM dual
UNION ALL SELECT 'A2', 'A1', 2 FROM dual
UNION ALL SELECT 'A2', 'A4', 2 FROM dual
UNION ALL SELECT 'A2', 'A5', 2 FROM dual
UNION ALL SELECT 'A3', 'A1', 3 FROM dual
UNION ALL SELECT 'A3', 'A5', 3 FROM dual
UNION ALL SELECT 'A4', 'A2', 3 FROM dual
UNION ALL SELECT 'A5', 'A3', 4 FROM dual
UNION ALL SELECT 'A5', 'A4', 4 FROM dual
UNION ALL SELECT 'A5', 'A5', 4 FROM dual
UNION ALL SELECT 'A5', 'A3', 4 FROM dual
)
SELECT *
  FROM (SELECT cd1, cd2, rank
             , ROW_NUMBER() OVER(PARTITION BY cd2 ORDER BY rank, cd1) rn
          FROM t
        )
 WHERE rn = 1
 ORDER BY rank, cd2
;

 


by 타잔 [2017.11.24 23:40:55]

급한 나머지 step2 결과가 잘못 되어 있네요.
월요일에 제대로 올리겠습니다.
감사합니다.


by 타잔 [2017.11.25 13:20:00]

Step2 수정했습니다.
가장 중요한 것은 Step1, Step2, Step3 ------ Step10000
이렇게 구현하는 것입니다.
제가 PL/SQL을 놓은지 오래돼서 PL로 하기엔 좀 어렵네요.
통계패키지 SAS이면 쉽게 구현하는데 SAS가 없네요. ㅜㅜ
한번더 검토 부탁드립니다.
감사합니다.


by 마농 [2017.11.25 14:06:58]

제 답변도 한번 더 검토 바랍니다.
굳이 반복처리가 필요 없을 듯 합니다. SQL 만으로 가능.
cd2 중복값중에 rank 가 가장 작은 값 하나만 남기고 나머지 제거하면 될 듯 하네요.


by 타잔 [2017.11.27 13:06:48]

제가 실제 데이터로 수행해 보니 마농님 답변이 맞네요.
대단히 감사합니다.
제가 3년 쉬다가 다시 SQL을 접하니 감이 사라졌나 보네요.

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