계층구조 테이블에서 질문이 있습니다 0 7 1,146

by 악어새 [Oracle 기초] 계층구조 부모 자식 최하단 [2019.05.14 15:56:23]



안녕하세요.

계층구조의 테이블에서 상위 계층이 들어왔을때 모든 최하단에 속한 데이터를 리턴하고 싶은데요,

우선 테이블 구조는 아래와 같습니다.

ID                   이름              부모의ID

------------------------------------------------

id000              S                   -

id001              A                   id000

id002              B                   id000

id003              A_01               id001

id004              A_02               id001

id005              B_01               id002

id006              A_11               id003

id007              A_21               id006

구조를 그림으로 표현한것이 첨부한 그림입니다.

이와같은 테이블 구조에서 만약 input data로

만약 A 가 들어온다면 A의 최하단 데이터인 A_21, A_02 를 찾아야 하고

S가 들어오면 A_21, A_02, B_01,

A_01 이 들어오면 A_21 을 찾고 싶습니다.

입력 데이터에 따라 뽑아내는 최하단 데이터도 다르게 뽑고싶은데요,

이 경우 어떻게 프로시저를 짜는것이 좋을지 조언이 필요합니다.

열심히 구글링 해보고 찾아보니 최하단을 찾는게 아니라 계층구조로 표현하는것이 대부분으로 나오더군요 ㅠㅠ

도움이나 의견 혹은 참고할만한 사이트라도 주시면 정말 감사하겠습니다.

by 이준환 [2019.05.14 16:56:47]
/*
2019.05.14
Jun H. Lee
*/
WITH T(ID, NM, PAR_ID)
AS
(
    SELECT 'id000', 'S', NULL FROM DUAL UNION ALL
    SELECT 'id001', 'A', 'id000' FROM DUAL UNION ALL
    SELECT 'id002', 'B', 'id000' FROM DUAL UNION ALL
    SELECT 'id003', 'A_01', 'id001' FROM DUAL UNION ALL
    SELECT 'id004', 'A_02', 'id001' FROM DUAL UNION ALL
    SELECT 'id005', 'B_01', 'id002' FROM DUAL UNION ALL
    SELECT 'id006', 'A_11', 'id003' FROM DUAL UNION ALL
    SELECT 'id007', 'A_21', 'id006' FROM DUAL
)
SELECT
SUBSTR(ID_OF_MAX_GEN_CNT, INSTR(ID_OF_MAX_GEN_CNT, '|', -1, 1)+1) AS LAST_ID_OF_MAX_GEN_CNT
FROM
(
    SELECT
    MAX(ID)KEEP(DENSE_RANK FIRST ORDER BY REGEXP_COUNT(ID, '\|') DESC, ID) AS ID_OF_MAX_GEN_CNT
    FROM
    (
        SELECT
          SYS_CONNECT_BY_PATH(NM, '|') AS ID
        FROM T
        START WITH NM = 'A' /*변수처리*/
        CONNECT BY PAR_ID = PRIOR ID
    )
)
;

 


by 악어새 [2019.05.14 17:02:40]

감사합니다 ! 모든 최하단 계층을 찾아주진 않지만 비슷한 방향으로 시도해보겠습니다!!


by 이준환 [2019.05.15 08:25:12]

세대수가 가장 긴 데이터를 찾는 것으로 잘못 이해했네요;

혼돈드려서 죄송합니다. ^.^;


by 랑에1 [2019.05.14 17:27:09]
SELECT NM
FROM 
(
	SELECT T.* 
	     , CONNECT_BY_ISLEAF leaf
	FROM T
	START WITH NM = 'A'
	CONNECT BY PRIOR id = par_id
)
WHERE leaf = 1

 

http://www.gurubee.net/lecture/1903 <- 여기 참조해보세요~


by 악어새 [2019.05.15 09:46:10]

답변 감사합니다 !!


by 마농 [2019.05.14 17:28:59]
WITH t AS
(
SELECT 'id000' id, 'S' nm, '-' pid FROM dual
UNION ALL SELECT 'id001', 'A'   , 'id000' FROM dual
UNION ALL SELECT 'id002', 'B'   , 'id000' FROM dual
UNION ALL SELECT 'id003', 'A_01', 'id001' FROM dual
UNION ALL SELECT 'id004', 'A_02', 'id001' FROM dual
UNION ALL SELECT 'id005', 'B_01', 'id002' FROM dual
UNION ALL SELECT 'id006', 'A_11', 'id003' FROM dual
UNION ALL SELECT 'id007', 'A_21', 'id006' FROM dual
)
SELECT *
  FROM t
 WHERE CONNECT_BY_ISLEAF = 1
 START WITH nm = :v_nm
 CONNECT BY PRIOR id = pid
;

 


by 악어새 [2019.05.15 09:46:19]

답변 감사합니다. 참고하여 수정해보겠습니다 !!!

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