2013-03-24 4 views
2

리프 수준에서 조건을 사용하여 계층 적 쿼리를 수행하려고합니다.잎 수준에 조건이있는 Oracle 재귀 계층 적 쿼리

나는 모든 아버지 필터링 쿼리 싶습니다

- 리프 수준이 조건을 statisfies 자식 관계 : ID LIKE '3 %가'

테이블 t은 다음과 같습니다

ParentId,Id 
INSERT INTO t VALUES ('VTE', 'VTP'); 
INSERT INTO t VALUES ('VTP', '202'); 
INSERT INTO t VALUES ('SER', '606'); 
INSERT INTO t VALUES ('SER', '609'); 
INSERT INTO t VALUES ('GIF', '301'); 
INSERT INTO t VALUES ('ECH', '302'); 
INSERT INTO t VALUES ('PUB', 'MER'); 
INSERT INTO t VALUES ('MER', '312'); 
INSERT INTO t VALUES ('MER', '313'); 
INSERT INTO t VALUES ('MER', '314'); 
INSERT INTO t VALUES ('MES', '318'); 
INSERT INTO t VALUES ('PUB', 'PRE'); 
INSERT INTO t VALUES ('PUB', 'PAP'); 
INSERT INTO t VALUES ('STA', '317'); 
INSERT INTO t VALUES ('NIV', 'ANS'); 
INSERT INTO t VALUES ('ZNM', '497'); 
INSERT INTO t VALUES ('ZNU', '496'); 
INSERT INTO t VALUES ('ANS', 'ZNC'); 
INSERT INTO t VALUES ('ZNC', '491'); 
INSERT INTO t VALUES ('NUL', 'NIV'); 
INSERT INTO t VALUES ('NIV', 'VTE'); 
INSERT INTO t VALUES ('VTE', 'VTC'); 
INSERT INTO t VALUES ('VTC', '100'); 
INSERT INTO t VALUES ('VTP', '204'); 
INSERT INTO t VALUES ('VTP', '205'); 
INSERT INTO t VALUES ('VTA', '500'); 
INSERT INTO t VALUES ('SER', '600'); 
INSERT INTO t VALUES ('NIV', 'PUB'); 
INSERT INTO t VALUES ('ECH', '303'); 
INSERT INTO t VALUES ('MER', '305'); 
INSERT INTO t VALUES ('MER', '306'); 
INSERT INTO t VALUES ('MER', '309'); 
INSERT INTO t VALUES ('PAP', '605'); 
INSERT INTO t VALUES ('SEP', 'PBC'); 
INSERT INTO t VALUES ('PBC', '601'); 
INSERT INTO t VALUES ('SEP', 'STA'); 
INSERT INTO t VALUES ('NIV', 'TRA'); 
INSERT INTO t VALUES ('ZNP', '498'); 
INSERT INTO t VALUES ('ANS', 'ZNM'); 
INSERT INTO t VALUES ('ANS', 'ZNE'); 
INSERT INTO t VALUES ('ANS', 'ZNR'); 
INSERT INTO t VALUES ('ZNR', '493'); 
INSERT INTO t VALUES ('ZNF', '492'); 
INSERT INTO t VALUES ('VTC', '101'); 
INSERT INTO t VALUES ('VTC', '102'); 
INSERT INTO t VALUES ('VTE', 'VTA'); 
INSERT INTO t VALUES ('VTE', 'SER'); 
INSERT INTO t VALUES ('AUT', '900'); 
INSERT INTO t VALUES ('PUB', 'CPR'); 
INSERT INTO t VALUES ('MER', '310'); 
INSERT INTO t VALUES ('MER', '311'); 
INSERT INTO t VALUES ('MER', '604'); 
INSERT INTO t VALUES ('PUB', 'MES'); 
INSERT INTO t VALUES ('MES', '316'); 
INSERT INTO t VALUES ('SEP', 'RSF'); 
INSERT INTO t VALUES ('RSF', '608'); 
INSERT INTO t VALUES ('TRA', 'TRP'); 
INSERT INTO t VALUES ('TRP', '603'); 
INSERT INTO t VALUES ('ANS', 'ZNP'); 
INSERT INTO t VALUES ('ANS', 'ZNU'); 
INSERT INTO t VALUES ('ANS', 'ZNG'); 
INSERT INTO t VALUES ('ANS', 'ZNF'); 
INSERT INTO t VALUES ('VTC', '104'); 
INSERT INTO t VALUES ('VTC', '105'); 
INSERT INTO t VALUES ('VTP', '200'); 
INSERT INTO t VALUES ('VTP', '201'); 
INSERT INTO t VALUES ('VTP', '203'); 
INSERT INTO t VALUES ('VTA', '400'); 
INSERT INTO t VALUES ('VTE', 'AUT'); 
INSERT INTO t VALUES ('CPR', '602'); 
INSERT INTO t VALUES ('PUB', 'GIF'); 
INSERT INTO t VALUES ('PUB', 'ECH'); 
INSERT INTO t VALUES ('MER', '307'); 
INSERT INTO t VALUES ('MER', '308'); 
INSERT INTO t VALUES ('PRE', '304'); 
INSERT INTO t VALUES ('PRE', '315'); 
INSERT INTO t VALUES ('NIV', 'SEP'); 
INSERT INTO t VALUES ('TRP', '607'); 
INSERT INTO t VALUES ('ANS', 'ZNA'); 
INSERT INTO t VALUES ('ZNA', '499'); 
INSERT INTO t VALUES ('ZNG', '495'); 
INSERT INTO t VALUES ('ZNE', '494'); 
COMMIT; 

나는 initialy 생각을 ECH의 아버지가 PUB 012,351,641입니다 (302)의 아버지가 ECH 예를 들어

SELECT ParentId, Id 
FROM t 
WHERE id LIKE '3%' 
start with ParentId ='NIV' 
CONNECT BY PRIOR Id = ParentId 

: 내가 좋아하는 뭔가를 사용할 수 있음PUB의 아버지는 NIV

하지만 쿼리는 레벨 0의 관계가 표시 (302)의 아버지가 ECH

입니다 그것은 루트에 모든 높은 수준을 폐기

: ECH의 아버지는 PUB PUB의 아버지가 NIV

입니다

나는 아래의 해결책을 생각해 냈습니다.

그러나 하위 - 부모 루프는 하드 코딩되어있어 하위 - 부모 관계의 수가 자동으로 식별되는 계층 적 쿼리의 목적을 무효화합니다.

SELECT parentid, id 
FROM t 
WHERE id IN 
    (SELECT parentid 
    FROM t 
    WHERE 
    id IN 
    (SELECT parentid 
     FROM t 
     WHERE id LIKE '3%' 
     start with parentid='NIV' 
     CONNECT BY PRIOR id = parentid) 
     start with parentid ='NIV' 
     CONNECT BY PRIOR id = parentid) 
OR 
ccomuse IN 
    (SELECT parentid 
    FROM t 
    WHERE id LIKE '3%' 
    start with parentid ='NIV' 
    CONNECT BY PRIOR id = parentid) 
OR 
id LIKE '3%' 
start with parentid ='NIV' 
CONNECT BY PRIOR id = parentid 

하드없이 모든 아동 부모 관계를 추출하는 방법이 있나요 자동으로 루트에 도달 재귀 적 방법 즉,이 내부 루프 코딩?

답변

0

sys_connect_by_path() 함수를 사용하여 계층 구조의 요소를 항목별로 분류하고 맨 오른쪽에서 필터링 했습니까? 모든 아버지를 필터링하려면

http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions171.htm#i1038266

+0

제안 해 주셔서 감사합니다. 간과 할 수도 있지만, 리프 수준 필터를 기반으로하는 Child-Father 관계가있는 2 열 테이블을 반환하는 sys_connect_by_path() 함수를 사용하는 방법을 실제로 이해하지 못합니다. – user2204154

0

봅니다

SELECT distinct ParentId, Id 
FROM t 
start with Id LIKE '3%' 
CONNECT BY Id = prior ParentId and Id <> 'NIV' 

fiddle

0

:-) 잘못된 끝에서 나무를 구축 - 자식 관계를 리프 수준이 다음 조건을 만족하는 경우 connect by 절에 조건을 지정해야합니다. 그것은 불필요한 노드와 출력에서 ​​자식 노드를 제거합니다. where 절에서 조건을 지정하면 자식 노드는 부모 노드없이 표시되므로 출력은 의미가 없습니다.