nachdem ich bei ähnlichen Fragestellungen in der Vergangenheit zu recht bizarren Lösungen unter Einsatz der sys_connect_by_path-Funktion und Parsen des gelieferten Strings über substr und instr gekommen war, bin ich inzwischen klüger geworden (möglicherweise auch nach Betrachtung der Erläuterungen zur neuen
recursive subquery factoring Syntax bei
Rob van Wijk) und habe folgende recht harmlose Query zum Umbau einer parent-child-Hierarchie in eine nicht normalisierte Matrix mit n-Ebenen geschrieben:
with
groups as
(select groupid
, groupname
, parentid
from ext_groups)
select ig0.groupid groupid_level0
, ig0.groupname groupname_level0
, ig1.groupid groupid_level1
, ig1.groupname groupname_level1
, ig2.groupid groupid_level2
, ig2.groupname groupname_level2
, ig3.groupid groupid_level3
, ig3.groupname groupname_level3
, ig4.groupid groupid_level4
, ig4.groupname groupname_level4
from
-- Root-Ebene
(select *
from groups
where parentid = 0
) ig0
-- Ebene 1
, (select *
from groups
) ig1
-- Ebene 2
, (select *
from groups
) ig2
-- Ebene 3
, (select *
from groups
) ig3
-- Ebene 4 (= Branch-Ebene)
, (select *
from groups
) ig4
where ig1.parentid = ig0.groupid
and ig2.parentid = ig1.groupid
and ig3.parentid = ig2.groupid
and ig4.parentid = ig3.groupid
order by ig0.groupid
, ig1.groupid
, ig2.groupid
, ig3.groupid
, ig4.groupid
Dabei werden die relevanten Spalten der Basistabelle (in diesem Fall eine external table) ext_groups über subquery factoring als groups verfügbar gemacht, dann auf Root-Ebene alle Elemente mit der parentId 0 ausgewählt (hier könnte natürlich auch ein NULL-Wert stehen) und anschließend alle weiteren Ebenen über Joins
= angeschlossen. Das Verfahren sollte auch für unbalancierte Hierarchien funktionieren, dabei müsste man sich aber noch Gedanken über die Formulierung der Outer-Joins machen.