ich ein wenig über zu kämpfen habe, wie man mit dieser Situation umgehen:Wie den Pfad einer Hierarchietabelle erhalten
Ich habe eine Tabelle wie folgt strukturiert:
Family_code | Parent_Family_Code | ....
1 2
2 4
3 6
4 3
......................
Wenn ein Benutzer für eine bestimmte Familie Code suchen, muss ich den ganzen Weg zurück (bis zu 10 Ebenen max), so zum Beispiel für family_code = 1 ich brauche werde:
Family_code | parent_1 | p_2 | p_3 | p_4 | p_5 | .....
1 2 4 3 6 null null.....
ich weiß, ich sys_connect_by_path()
verwenden können Das bringt mir das erwartete Ergebnis aber als String, und nicht als separate Spalten, was ich lieber vermeiden möchte.
Dies kann auch mit 10 linken Verknüpfungen zu der gleichen Tabelle oder die Verwendung von LEAD()/LAG()
Funktionen, die eine Menge von Unterabfragen enthalten wird und eine unordentliche und unleserliche Abfrage machen, aber wiederum wird dies schwerer sein dann sollte es sein und ich muss es so vereinfachen wie ich kann.
Ich habe mit einer Lösung mit substr()
Funktion kommen (die Länge der Codes immer varchar2 sein (3)):
SELECT s.family_code,
s.parent_family_code_1,
s.parent_family_code_2,
CASE WHEN length(s.family_path) - (4 * 3 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 3 + 2), 3) ELSE NULL END as parent_family_code_3,
CASE WHEN length(s.family_path) - (4 * 4 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 4 + 2), 3) ELSE NULL END as parent_family_code_4,
CASE WHEN length(s.family_path) - (4 * 5 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 5 + 2), 3) ELSE NULL END as parent_family_code_5,
CASE WHEN length(s.family_path) - (4 * 6 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 6 + 2), 3) ELSE NULL END as parent_family_code_6,
CASE WHEN length(s.family_path) - (4 * 7 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 7 + 2), 3) ELSE NULL END as parent_family_code_7,
CASE WHEN length(s.family_path) - (4 * 8 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 8 + 2), 3) ELSE NULL END as parent_family_code_8,
CASE WHEN length(s.family_path) - (4 * 9 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 9 + 2), 3) ELSE NULL END as parent_family_code_9,
CASE WHEN length(s.family_path) - (4 * 10 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 10 + 2), 3) ELSE NULL END as parent_family_code_10
FROM (SELECT t.family_code,
t.parent_family_code as parent_family_code_1,
prior t.parent_family_code as parent_family_code_2,
sys_connect_by_path(t.family_code, ',') as family_path
FROM table t
connect by prior t.family_code = t.parent_family_code) s
Aber ich würde, da es eine Lösung ohne die Verwendung von Teil mag es wird schwieriger sein, irgendwas daran zu ändern, wenn andere Entwickler es berühren werden . Also meine Frage ist im Grunde - wie wähle ich den gesamten Pfad als verschiedene Spalten ohne die Verwendung von Substrings?
Der Code, den Sie in die Frage bearbeitet haben nicht funktioniert - wenn Sie werden auch 'SELECT family_path' sehen, dann sehen Sie, dass (a) es nicht den gesamten Pfad erhält und (b) der Pfad nicht vollständig von den Sub-Strings verarbeitet wird, da Sie Strings variabler Länge haben und Fixed-Length-Bedingungen verwenden. – MT0
Wenn Sie den gesamten Pfad haben möchten, können Sie 'sys_connect_by_path (t.parent_family_code, ',') || verwenden ',' || t.family_code als family_path', löst aber immer noch nicht die zweite Ausgabe von Daten variabler Länge und fester Längen in den Fallbedingungen. – MT0