2016-04-05 10 views
0

ich eine Tabelle Test haben dieSQL Ersatz für rekursive CTE

TEST 
---- 
tablename|columnvalue|rankofcolumn 
A|C1|1 
A|C2|2 
A|C3|3 
A|C4|4 
B|CX1|1 
B|CX2|2 
C|CY1|1 
C|CY2|2 
C|CY3|3 

enthält möchte ich zusammen mit anderen Spalten den Pfad zu erzeugen, wie

RESULT 
---- 
tablename|columnvalue|rankofcolumn|path 
A|C1|1|C1 
A|C2|2|C1->C2 
A|C3|3|C1->C2->C3 
A|C4|4|C1->C2->C3->C4 
B|CX1|1|CX1 
B|CX2|2|CX1->CX2 
C|CY1|1|CY1 
C|CY2|2|CY1->CY2 
C|CY3|3|CY1->CY2->CY3 

folgt Per dieser question, kann ich rekursiv verwenden CTE, um dies zu erreichen

WITH r (tablename, columnvalue, rankofcolumn, PATH) AS 
     (SELECT tablename, 
        columnvalue, 
        rankofcolumn, 
        columnvalue 
      FROM  test 
      WHERE  rankofcolumn = 1 
      UNION ALL 
      SELECT xx.tablename, 
        xx.columnvalue, 
        xx.rankofcolumn, 
        r.PATH || '->' || xx.columnvalue 
      FROM  r 
        JOIN test xx 
         ON  xx.tablename = r.tablename 
          AND xx.rankofcolumn = r.rankofcolumn + 1) 
SELECT * 
FROM  r; 

Aber ich benutze WX2-Datenbank, die diese Option fehlt bei der Moment. Gibt es dafür eine SQL-Alternative?

+0

WX2 wird nicht die CTE erleichtern oder Sie fragen eine andere Lösung für diese Ausgabe – mohan111

+0

In der vorherigen Frage haben Sie gesagt, dass Zwischentabellen erlaubt waren; ist das immer noch in Ordnung? –

+0

@AlexPoole Ja. Wir können Zwischentabellen oder Ansichten haben. – SriniV

Antwort

1

Sie könnten den Brute-Force-Ansatz mit einer Tabelle ausführen, die Sie schrittweise füllen. Angenommen, Ihre test Tabelle sieht etwa so aus:

create table test (tablename varchar2(9), columnvalue varchar2(11), rankofcolumn number); 

dann die result Tabelle kann erstellt werden:

create table result (tablename varchar2(9), columnvalue varchar2(11), rankofcolumn number, 
    path varchar2(50)); 

Dann erstellen die Ergebniseinträge für den niedrigsten Rang:

insert into result (tablename, columnvalue, rankofcolumn, path) 
select t.tablename, t.columnvalue, t.rankofcolumn, t.columnvalue 
from test t 
where t.rankofcolumn = 1; 

3 rows inserted. 

Und immer wieder Fügen Sie Zeilen hinzu, die auf dem höchsten vorhandenen Rang aufbauen und erhalten die folgenden Werte (wenn es dafür tablename gibt) von th e test Tabelle:

insert into result (tablename, columnvalue, rankofcolumn, path) 
select t.tablename, t.columnvalue, t.rankofcolumn, 
    concat(concat(r.path, '->'), t.columnvalue) 
from test t 
join result r 
on r.tablename = t.tablename 
and r.rankofcolumn = t.rankofcolumn - 1 
where t.rankofcolumn = 2; 

3 rows inserted. 

insert into result (tablename, columnvalue, rankofcolumn, path) 
select t.tablename, t.columnvalue, t.rankofcolumn, 
    concat(concat(r.path, '->'), t.columnvalue) 
from test t 
join result r 
on r.tablename = t.tablename 
and r.rankofcolumn = t.rankofcolumn - 1 
where t.rankofcolumn = 3; 

2 rows inserted. 

insert into result (tablename, columnvalue, rankofcolumn, path) 
select t.tablename, t.columnvalue, t.rankofcolumn, 
    concat(concat(r.path, '->'), t.columnvalue) 
from test t 
join result r 
on r.tablename = t.tablename 
and r.rankofcolumn = t.rankofcolumn - 1 
where t.rankofcolumn = 4; 

1 row inserted. 

Und halten Sie für die maximal mögliche Anzahl der Spalten gehen (d höchste rankofcolumn für jede Tabelle). Sie können dies prozedural in WX2 tun, indem Sie so lange iterieren, bis Nullzeilen eingefügt werden. aber du hast es ziemlich begrenzt klingen lassen.

Nach all den Wiederholungen der Tabelle jetzt enthält:

select * from result 
order by tablename, rankofcolumn; 

TABLENAME COLUMNVALUE RANKOFCOLUMN PATH            
--------- ----------- ------------ -------------------------------------------------- 
A   C1      1 C1             
A   C2      2 C1->C2            
A   C3      3 C1->C2->C3           
A   C4      4 C1->C2->C3->C4          
B   CX1     1 CX1            
B   CX2     2 CX1->CX2           
C   CY1     1 CY1            
C   CY2     2 CY1->CY2           
C   CY3     3 CY1->CY2->CY3          

in Oracle getestet, aber versuchen, etwas Oracle-spezifischen zu vermeiden; könnte für WX2 natürlich optimieren müssen.

+0

Danke @Alex auf diesem Bit. Aber wenn wir alle diese Schritte in einem JOIN tun können ?? Ich kann eine Config-Tabelle haben, um die Level zu sagen und ein CROSS JOIN zu machen, um das zu erreichen? – SriniV

+0

Nicht ohne Rekursion. Sie können nicht innerhalb einer Auswahl erstellen/einfügen; das ist teilweise warum CTEs nützlich sind. Du könntest, denke ich, ein (nicht-rekursives) CTE haben, das eine Reihe von Unionen macht, mit zunehmend mehr Self-Joins in jedem einzelnen, aber das ist noch unordentlicher. –

+0

Schätzen Sie diese echte Anstrengung von Ihnen. Danke Kumpel – SriniV