2013-03-24 75 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想我可以使用類似:

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

例如, 302的父親是ECH ECH的父親是PUB 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 

有沒有一種方法來提取所有的孩子 - 父母關係,而不用硬編碼2內部循環,即用自動到達根的遞歸方法?

回答

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子句中指定條件,則子節點將在沒有父節點的情況下顯示,因此輸出將不會有意義。