A | B |
1 | 2 |
2 | 5 |
5 | 10 |
2 | 20 |
20 | 18 |
... | ... |
A 컬럼 1 기준으로 B 이후 컬럼이 다시 A 컬럼이 되서 데이터가 형성됩니다(?)
1은 2로, 2는 다시 5와 10으로 분기됩니다.
1->2->5->10(끝)
1->2->20->18(끝)
최종 원하는 형식은
1dep | 2dep | 3dep | 순번 | |
1 | 2 | 5 | 1 | |
1 | 2 | 10 | 2 | |
1 | 2 | 20 | 1 | |
1 | 2 | 18 | 2 |
쿼리로 머리를 돌려봤는데 잘 안되서요 ㅠ 프로시저로 짜야할까요..쿼리로 가능할까요
WITH T AS ( SELECT 1 ACOL,2 BCOL FROM DUAL UNION ALL SELECT 2,5 FROM DUAL UNION ALL SELECT 5,10 FROM DUAL UNION ALL SELECT 2,20 FROM DUAL UNION ALL SELECT 20,18 FROM DUAL ) SELECT DEP1, DEP2, NVL(DEP4,DEP3) DEP3, NVL2(DEP4,2,1) SEQ FROM ( SELECT CONNECT_BY_ROOT(ACOL) DEP1 , REPLACE(SYS_CONNECT_BY_PATH(DECODE(LEVEL,1,BCOL),'-'),'-') DEP2 , REPLACE(SYS_CONNECT_BY_PATH(DECODE(LEVEL,2,BCOL),'-'),'-') DEP3 , REPLACE(SYS_CONNECT_BY_PATH(DECODE(LEVEL,3,BCOL),'-'),'-') DEP4 FROM T WHERE LEVEL > 1 START WITH ACOL = '1' CONNECT BY PRIOR BCOL = ACOL )
depth가 4까지인가요?
데이터는
SELECT * FROM ( SELECT '1' ACOL,'2' BCOL FROM DUAL UNION ALL SELECT '2','#' FROM DUAL UNION ALL SELECT '2','28' FROM DUAL UNION ALL SELECT '28','29' FROM DUAL UNION ALL SELECT '29','30' FROM DUAL UNION ALL SELECT '31','#' FROM DUAL UNION ALL SELECT '53','54' FROM DUAL UNION ALL SELECT '54','45' FROM DUAL UNION ALL SELECT '45','22' FROM DUAL UNION ALL SELECT '45','#' FROM DUAL UNION ALL SELECT '8','38' FROM DUAL UNION ALL SELECT '38','7' FROM DUAL UNION ALL SELECT '7','2' FROM DUAL UNION ALL SELECT '2','#' FROM DUAL UNION ALL SELECT '2','28' FROM DUAL UNION ALL SELECT '28','29' FROM DUAL UNION ALL SELECT '29','30' FROM DUAL UNION ALL SELECT '30','31' FROM DUAL UNION ALL SELECT '7','5' FROM DUAL UNION ALL SELECT '5','4' FROM DUAL UNION ALL SELECT '4','3' FROM DUAL UNION ALL SELECT '4','17' FROM DUAL UNION ALL SELECT '17','30' FROM DUAL ) ;
이렇게 적재가 되어 있구요.
자료의 흐름이 이런 식으로 직렬 뿐만아니라 병렬로도... 가능해요.
상위 코드가 1, 53, 8로 예시를 들었지만 질의 결과에 따라서 상위코드는 변경될수 있구요
1. 제가 샘플을 만들다 보니 중복자료가 들어갔네요ㅠ 중복은 없어요.
2. 시설의 배출경로를 만드는 데이터에요. 배출경로 부모 테이블에는 시설과 상위 배출경로가 명시되어 있어요
예를 들면, A 시설의 배출시설이 1, 53, 8 인거죠.
시설 조건이 달라지면 상위 배출경로가 달라질수 있어요. B 시설의 경우 30, 31, 32로 결과가 나오면
30, 31, 32 모두에 대해 배출경로를 하단까지 찾아야 되요
3. 결과자료에 대해서 좀더 고민을 해야할것 같아요ㅠㅠ 저렇게 여러 댑스에서 병렬처리 되는 경우, 3댑스와 순번만으로는 표시가 어려울것 같아요
4. 그림은 데이터 여러 케이스를 설명하고자 그린 그림이고, 실제 데이터는 아직 정확히 정의되지 않아서요. 이부분 협의후에 진행하는걸로 결론은 났어요
다만, 데이터가 3댑스까지만 병렬처리되고, 그 이후 자료는 모두 직렬일 경우
2번의 경우 상위 배출경로(A COL)가 부모테이블에 질의 된 결과가 달라지면 어떤식으로 쿼리해야될지 잘 몰라서요
나중에 데이터 셋이랑 다시 한번 질의를 해보겠습니다. 감사합니다!
ROOT는 부모테이블에서 질의해서 확인할수 있어요
부모컬럼에서 질의 결과가 1, 53, 8로 나온 경우를 예로 든거구요
만약 질의결과가 다른 번호가 된다면 "START WITH ACOL = '1'" 이 부분이 달라질텐데
IN 조건으로 넣으면, 상위 SQL의 다른 데이터를 못가져오고..
JOIN 조건으로 해서 넣자니 데이터가 안맞아요서요.. (제말이 좀 헷갈리시죠 ㅠ)
트리관련 컬럼은 2개밖에 없어요. 중간가지 알수 없구요. 현재 구조상.
Q.예를 들어 1-2-8->16인 데이터와 5->8->16인 데이터가 있다면 8->16인 데이터가 2개 존재할텐데요.
A. 8, 16 하나만 존재해요.
3댑스이상일때 표현기준이 모호해서 표출방법이 변경될것 같아요
데이터셋이 명확하지 않아서..ㅠ
나중에 데이터셋과 다시 한번 질의해보겠습니다. 감사합니다!
링크 그림의 자료를 계층구조로 표현해 봤습니다. 참고하세요.
WITH t1 AS ( SELECT '2' cd, '1' pcd FROM dual UNION ALL SELECT '#', '2' FROM dual UNION ALL SELECT '28', '2' FROM dual UNION ALL SELECT '28', '1' FROM dual UNION ALL SELECT '29', '28' FROM dual UNION ALL SELECT '30', '29' FROM dual UNION ALL SELECT '31', '30' FROM dual UNION ALL SELECT '54', '53' FROM dual UNION ALL SELECT '45', '54' FROM dual UNION ALL SELECT '22', '45' FROM dual UNION ALL SELECT '#', '45' FROM dual UNION ALL SELECT '38', '8' FROM dual UNION ALL SELECT '7', '38' FROM dual UNION ALL SELECT '2', '7' FROM dual UNION ALL SELECT '5', '7' FROM dual UNION ALL SELECT '4', '5' FROM dual UNION ALL SELECT '3', '4' FROM dual UNION ALL SELECT '17', '4' FROM dual UNION ALL SELECT '30', '17' FROM dual ) , t2 AS ( SELECT 'A' gb, '1' cd FROM dual UNION ALL SELECT 'A', '53' FROM dual UNION ALL SELECT 'A', '8' FROM dual ) SELECT cd, pcd , LEVEL lv , CONNECT_BY_ROOT(pcd) root_cd , SYS_CONNECT_BY_PATH(cd, '-') p FROM t1 START WITH pcd IN (SELECT cd FROM t2 WHERE gb = 'A') CONNECT BY PRIOR cd = pcd ;