2011-01-11 9 views
7

Ich habe die folgende Tabelle in einem Orakel:Rekursion In Oracle

Parent(arg1, arg2) 

und ich möchte die transitive Schließung der Beziehung Eltern. Das heißt, ich möchte die folgende Tabelle

Ancestor(arg1, arg2) 

Wie ist das in Oracle möglich?

ich folgendes tue:

WITH Ancestor(arg1, arg2) AS (

    SELECT p.arg1, p.arg2 from parent p 
    UNION 
    SELECT p.arg1 , a.arg2 from parent p, Ancestor a 
    WHERE p.arg2 = a.arg1 

) 

SELECT DISTINCT * FROM Ancestor; 

Ich erhalte den Fehler

*Cause: column aliasing in WITH clause is not supported yet 
*Action: specify aliasing in defintion subquery and retry 
Error at Line: 1 Column: 20 

Wie kann ich diese ohne Spalte Aliasing lösen?

Antwort

22
WITH Ancestor(arg1, arg2) AS 
     (
     SELECT p.arg1, p.arg2 
     FROM parent p 
     WHERE arg2 NOT IN 
     (
      SELECT arg1 
      FROM parent 
     ) 

     UNION ALL 

     SELECT p.arg1, a.arg2 
     FROM Ancestor a 
     JOIN parent p 
     ON  p.arg2 = a.arg1 
     ) 
SELECT * 
FROM Ancestor 

Oracle unterstützt nur rekursive CTE seit 11g Release 2.

In früheren Versionen verwenden CONNECT BY Klausel:

SELECT arg1, CONNECT_BY_ROOT arg2 
FROM parent 
START WITH 
     arg2 NOT IN 
     (
     SELECT arg1 
     FROM parent 
     ) 
CONNECT BY 
     arg2 = PRIOR arg1 
+8

11g Release '2' um genau zu sein –