2013-10-16 2 views
1

저는 Oracle 초보자입니다 ... 비교적 말하기 ...조부모 및 어린이 자녀를 찾기위한 Oracle CTE

내가 상속 한 Oracle 테이블에서 CTE를 사용하려고합니다. "최상위 수준"이 명확하게 정의되어 있지 않기 때문에 나는 기대했던 것보다 조금 더 복잡합니다.

create table testConnectBy (parent number, child number); 

insert into testConnectBy values (1, 1); 
insert into testConnectBy values (1, 11); 
insert into testConnectBy values (1, 12); 
insert into testConnectBy values (2, 2); 
insert into testConnectBy values (2, 13); 
insert into testConnectBy values (11, 11); 
insert into testConnectBy values (11, 20); 
insert into testConnectBy values (11, 21); 
insert into testConnectBy values (12, 12); 
insert into testConnectBy values (12, 22); 
insert into testConnectBy values (12, 23); 
insert into testConnectBy values (12, 24); 
insert into testConnectBy values (13, 13); 
insert into testConnectBy values (13, 30); 
insert into testConnectBy values (13, 31); 
insert into testConnectBy values (30, 30); 
insert into testConnectBy values (30, 40); 

이 쿼리가 필요한 모든 행을 얻을 수 있지만 (그것이 가장 제거하는 방법 질문, 내 생각의 첫 번째 부분입니다)에서 일부 중복이 있습니다. 루프 문제 (부모 == 자식)가 있으므로 nocycle을 포함해야했습니다.

다음 호는 예를 들어 11을 입력하고 모든 부모와 자녀를 찾을 수 있기를 바랍니다. 어떤 부모 나 자녀가 11과 관련이 있는지 알 수 없습니다. 단지 이것을 사용하여 찾을 필요가 있습니다.

이 쿼리는 11 명의 자식 만 반환합니다. 두 방향 모두를 반환하는 방법이 있습니까?

select * 
    from testConnectBy 
    start with parent = '11' 
    connect by nocycle prior child = parent; 

미리 감사드립니다.

답변

1

첫 번째 질문에 대해서는 아래를 사용하십시오. 그것은 어떤 그런 다음 부모 = 아동을 피하려면이

1 1 1 0 1 1 ~ 1 
1 11 2 0 1 1 ~ 1 ~ 11 
11 20 3 1 0 1 ~ 1 ~ 11 ~ 20 
11 21 3 1 0 1 ~ 1 ~ 11 ~ 21 
1 12 2 0 1 1 ~ 1 ~ 12 
12 22 3 1 0 1 ~ 1 ~ 12 ~ 22 
12 23 3 1 0 1 ~ 1 ~ 12 ~ 23 
12 24 3 1 0 1 ~ 1 ~ 12 ~ 24 
1 11 1 0 1 1 ~ 11 
11 20 2 1 0 1 ~ 11 ~ 20 
11 21 2 1 0 1 ~ 11 ~ 21 
1 12 1 0 1 1 ~ 12 
12 22 2 1 0 1 ~ 12 ~ 22 
12 23 2 1 0 1 ~ 12 ~ 23 
12 24 2 1 0 1 ~ 12 ~ 24 

를 반환합니다

SELECT 
      PARENT, 
      CHILD, 
      LEVEL, 
      CONNECT_BY_ISLEAF AS ISLEAF, 
      CONNECT_BY_ISCYCLE AS ISCYCLE, 
      CONNECT_BY_ROOT PARENT 
      || SYS_CONNECT_BY_PATH (CHILD, 
           ' ~ ') 
       AS PATH 
     FROM 
      TESTCONNECTBY 
     CONNECT BY 
      NOCYCLE PARENT = PRIOR CHILD 
     START WITH 
      PARENT = '1'; 

PATH에 확인할 수 있습니다 중복,

SELECT 
      PARENT, 
      CHILD, 
      LEVEL, 
      CONNECT_BY_ISLEAF AS ISLEAF, 
      CONNECT_BY_ISCYCLE AS ISCYCLE, 
      CONNECT_BY_ROOT PARENT 
      || SYS_CONNECT_BY_PATH (CHILD, 
           ' ~ ') 
       AS PATH 
     FROM 
      (SELECT * FROM TESTCONNECTBY WHERE PARENT <> CHILD) 
     CONNECT BY 
      NOCYCLE PARENT = PRIOR CHILD 
     START WITH 
      PARENT = '1'; 

결과가 없습니다 are

1 11 1 0 0 1 ~ 11 
11 20 2 1 0 1 ~ 11 ~ 20 
11 21 2 1 0 1 ~ 11 ~ 21 
1 12 1 0 0 1 ~ 12 
12 22 2 1 0 1 ~ 12 ~ 22 
12 23 2 1 0 1 ~ 12 ~ 23 
12 24 2 1 0 1 ~ 12 ~ 24 

fo R 당신은 두 번째 질문, 아래

SELECT 
     * 
FROM 
     (SELECT 
      PARENT, 
      CHILD, 
      LEVEL, 
      CONNECT_BY_ISLEAF AS ISLEAF, 
      CONNECT_BY_ISCYCLE AS ISCYCLE, 
      CONNECT_BY_ROOT PARENT 
      || SYS_CONNECT_BY_PATH (CHILD, 
           ' ~ ') 
       AS PATH 
     FROM 
      (SELECT * FROM TESTCONNECTBY WHERE PARENT <> CHILD) 
     CONNECT BY 
      NOCYCLE PARENT = PRIOR CHILD 
     START WITH 
      PARENT = '1') 
WHERE 
     PARENT = 11 
     OR CHILD = 11; 
다음, 당신이 자기 아이들을 제외 할 경우 부모 (11)이 아이 (11)가 있기 때문에

SELECT 
     * 
FROM 
     (SELECT 
      PARENT, 
      CHILD, 
      LEVEL, 
      CONNECT_BY_ISLEAF AS ISLEAF, 
      CONNECT_BY_ISCYCLE AS ISCYCLE, 
      CONNECT_BY_ROOT PARENT 
      || SYS_CONNECT_BY_PATH (CHILD, 
           ' ~ ') 
       AS PATH 
     FROM 
      TESTCONNECTBY 
     CONNECT BY 
      NOCYCLE PARENT = PRIOR CHILD 
     START WITH 
      PARENT = '1') 
WHERE 
     PARENT = 11 
     OR CHILD = 11; 

이 쿼리는

1 11 2 0 1 1 ~ 1 ~ 11 
11 20 3 1 0 1 ~ 1 ~ 11 ~ 20 
11 21 3 1 0 1 ~ 1 ~ 11 ~ 21 
1 11 1 0 1 1 ~ 11 
11 20 2 1 0 1 ~ 11 ~ 20 
11 21 2 1 0 1 ~ 11 ~ 21 

를 반환 니펫을 사용할 수 있습니다 반환

1 11 1 0 0 1 ~ 11 
11 20 2 1 0 1 ~ 11 ~ 20 
11 21 2 1 0 1 ~ 11 ~ 21 
+0

응답 해 주셔서 감사합니다. 불행히도 마지막 쿼리에서 PARENT = '1'을 사용합니다. 나는 부모가 '1'이라는 것을 알지 못할 것이다. '11'만 계층 구조의 어딘가에 있습니다. –

+0

나는 1로 시작하여 전체 계층 구조를 취합니다. 11에 대해 필터링합니다. – SriniV

+0

아, 그냥 경로에있는 것으로 나타났습니다. 그래서 나는 그 필드를 추출해야하고 그것으로 무언가를해야합니다. –