sql로 가능할까요... 0 18 3,679

by 제리공주 [2016.11.23 16:44:20]


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  

쿼리로 머리를 돌려봤는데 잘 안되서요 ㅠ 프로시저로 짜야할까요..쿼리로 가능할까요

by jkson [2016.11.23 17:22:55]
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까지인가요?


by 제리공주 [2016.11.24 10:15:32]

감사합니다. 뎁스는 더 많지만 3개 뎁스 형태로만 출력이 되야해요 ~~

계층순환쿼리로 저도 해보곤 있는데 잘 안되네요

답변 너무 감사합니다!


by 제리공주 [2016.11.24 10:28:37]

만약, 1댑스가 1로 시작이 아니라, 다양한 데이터가 있다면 어떻게 수정해야할까요?


by 마농 [2016.11.23 17:58:23]

좀 더 다양한 형태의 예시가 있으면 좋겠는데요.
현재 예제는 너무 평범하여 복잡한 경우가 발생 가능한지 알 수 없네요.
  - 4레벨 까지만 존재하는지? 그 이상 내려가는게 가능한지?
  - 4레벨까지 못내려가고 2,3 레벨에서 끝나는 경우도 존재하는지?
  - 동일 3레벨 부모를 가지는 4레벨 자식이 여러개 존재 가능한지?
  - 1레벨의 값은 하나뿐인지? 여러개인지?


by 제리공주 [2016.11.24 10:17:09]

말씀하신 모든 경우의 수가 존재합니다.  결과는 3뎁스에 표현을 해야해요.

순환쿼리로 작성은 해봤는데 여러 테이블 조인해서 하다보니 잘 안되네요 ㅠㅠ


by 제리공주 [2016.11.24 10:23:50]

예를 들면,

1->2->종료

1->2->28->29->30->31->종료

5->4->3->종료

5->4->3->31->종료

이런 경우,

1 / 2 / NULL / 순번1

1 / 2/ 28 / 순번1

1 / 2/ 29 / 순번2

1 / 2/ 30 / 순번3

1 / 2/ 31 / 순번4

1 / 2 / NULL / 순번5

5 / 4 / 3 / 순번 1

5 / 4 / NULL / 순번2

5 / 4 / 3 / 순번1

5 / 4 / 31 / 순번 2

5 / 4 / NULL / 순번3

 

이런 형태로요..

 

 

 


by 마농 [2016.11.24 10:35:13]

그 모든 경우의 수를 예를 들어 주세요. 원본 대비 결과표로.
순번이 어떤 방식으로 매겨져야 하는지를 명확하게 알아야 합니다.


위에 추가로 드신 예는 모호합니다.
논리적으로 앞뒤가 안맞네요.
  - 1->2->종료 라 하고난 후, 그 다음에 28 이 또 연결되고 있구요.
모든 경우가 다 들어 있는 것도 아니구요.
  - 3레벨 이후로 자식이 아래로 여러개인 경우만 있고 옆으로 여러개인 경우가 없네요.
텍스트 형식이 아닌
  - 실제 테이블 형태로 보여주세요.


by 제리공주 [2016.11.24 11:01:45]

데이터가 직렬 연결이 아니라, 병렬로 연결 된 경우( 1개 이상으로 분기되는 경우가 있어서..)

2가 "종료"로 가는 경우도 있고, "28"로 가는 경우도 있어요. 3개로 분기될 수도 있구요.

말씀하신 대로 자료를 샘플을 만들다 보니 4댑스 이상에서 병렬처리인 경우 자료 표기 방법이

모호해서요. 이 부분은 정리가 되면 다시 도움 요청드리겠습니다. 답변 너무 감사드립니다.

그런데 상위코드가 START WITH ACOL 가 질의된 결과에 따라 다르면, 이부분은 어떻게 표시해야되나요?

 


by 마농 [2016.11.24 11:06:20]

질문이 계속 모호합니다.

예시 자료를 만들다 보니 스스로도 모호하다는 것을 느끼신듯 하네요.

추가 질문인 start with 부분도 무슨 뜻인지 모르겟네요.

명확한 예시 자료를 만들어 보세요.

질문이 모호해지면 답변을 달 수 없습니다.

종료로 끝나기도 하고 아니기도 하다는 표현도 선듯 이해가지 않는 부분이구요.


by 제리공주 [2016.11.24 11:13:38]

데이터는

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로 예시를 들었지만 질의 결과에 따라서 상위코드는 변경될수 있구요

 

 

 


by 마농 [2016.11.24 11:27:13]

예시자료에 데이터 중복이 보이구요.
  - 데이터는 중복되지 않아야 합니다.
조회 조건에 따라 예시가 달라진다면?
  - 해당 조회 조건으로 예시자료를 추출해 내는 쿼리가 있다면 보여주세요. 실 테이블과 함께.
예시자료만 있네요.
  - 그에 따른 결과자료도 보여주세요.
링크의 그림이 원본인가요
  - 실제 원본 테이블이 존재하지 않는 건가요?


by 제리공주 [2016.11.24 11:56:07]

1. 제가 샘플을 만들다 보니 중복자료가 들어갔네요ㅠ 중복은 없어요.
2. 시설의 배출경로를 만드는 데이터에요. 배출경로 부모 테이블에는 시설과 상위 배출경로가 명시되어 있어요
   예를 들면, A 시설의 배출시설이 1, 53, 8 인거죠. 
   시설 조건이 달라지면 상위 배출경로가 달라질수 있어요. B 시설의 경우 30, 31, 32로 결과가 나오면
   30, 31, 32 모두에 대해 배출경로를 하단까지 찾아야 되요
3. 결과자료에 대해서 좀더 고민을 해야할것 같아요ㅠㅠ 저렇게 여러 댑스에서 병렬처리 되는 경우, 3댑스와 순번만으로는 표시가 어려울것 같아요
4. 그림은 데이터 여러 케이스를 설명하고자 그린 그림이고, 실제 데이터는 아직 정확히 정의되지 않아서요. 이부분 협의후에 진행하는걸로 결론은 났어요

다만, 데이터가 3댑스까지만 병렬처리되고, 그 이후 자료는 모두 직렬일 경우
     2번의 경우 상위 배출경로(A COL)가 부모테이블에 질의 된 결과가 달라지면 어떤식으로 쿼리해야될지 잘 몰라서요
     나중에 데이터 셋이랑 다시 한번 질의를 해보겠습니다. 감사합니다!


by jkson [2016.11.24 11:32:30]

우올~ 어려운 문제군요. 트리관련 컬럼이 두개 밖에 없어요? root는 어떻게 확인하는 거죠? 소팅된 데이터인 것 같은데 소트 안 되어있을 때 중간 가지가 어디서 나온 건지는 어떻게 확인 가능할까요?

예를 들어 1-2-8->16인 데이터와 5->8->16인 데이터가 있다면 8->16인 데이터가 2개 존재할텐데요.

링크 그림만 봐도 1번 트리에서 2->28도 있고 3번 트리에서 2->28도 있네요. 3depth까지 표현한다고 했을 때 순번컬럼의 기준은요?


by 제리공주 [2016.11.24 11:56:29]

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댑스이상일때 표현기준이 모호해서 표출방법이 변경될것 같아요
데이터셋이 명확하지 않아서..ㅠ
나중에 데이터셋과 다시 한번 질의해보겠습니다. 감사합니다!


by 마농 [2016.11.24 12:21:43]

링크 그림의 자료를 계층구조로 표현해 봤습니다. 참고하세요.

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
;

 


by 제리공주 [2016.11.24 13:27:15]

감사합니다 ㅠㅠ

실 테이블에 적용해보니, JDBC-11004:Invalid function argument. 오류가 나더라구요(티베로라..)

확인해보니 데이터 상에 무한 루프 존재해요. 28->29->30->28 다시 28로 회귀하는;;;

데이터 이상인것 같긴 한데, 이런 경우 28->29->30 까지만 끊을수 있을까요?

 

 


by 마농 [2016.11.24 13:34:17]

- 변경전 : CONNECT BY

- 변경후 : CONNECT BY NOCYCLE


by 제리공주 [2016.11.24 13:54:00]

아 아규먼트 오류 원인 확인했어요.. 무한루프때문이 아니라(이것도 문제긴 했지만^^;)

실제 데이터에는 '-'가 포함되어 있어서

발생하는 오류였어요. 감사합니다.. 너무너무~!!! ㅠㅠ

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