Ich habe ein einfaches Beispiel zur Veranschaulichung der transitiven Schließung mit rekursiven Abfragen in PostgreSQL erstellt.
Allerdings ist etwas mit meiner rekursiven Abfrage nicht möglich. Ich bin mit der Syntax noch nicht vertraut, daher kann diese Bitte ganz und gar nichts von mir sein, und dafür entschuldige ich mich im Voraus. Wenn Sie die Abfrage ausführen, sehen Sie, dass Knoten 1 sich in den Pfadergebnissen wiederholt. Kann mir bitte jemand helfen, herauszufinden, wie man das SQL optimiert?
%Vor% Sie können an mehreren Stellen vereinfachen (angenommen acct_id
und parent_id
sind NOT NULL
):
acct_id
, depth
, cycle
sind nur Rauschen in Ihrer Abfrage. WHERE
muss die Rekursion einen Schritt früher beenden, bevor der doppelte Eintrag vom obersten Knoten im Ergebnis ist. Das war ein "Off-by-One" in Ihrem Original. Der Rest ist Formatierung.
Wenn Sie wissen , dass der einzige mögliche Kreis in Ihrem Graphen eine Selbstreferenz ist, können wir das billiger haben:
%Vor% Beachten Sie, dass es für Datentypen mit einem Modifizierer (wie varchar(5)
) Probleme (mindestens bis pg v9.4) geben würde, weil die Array-Verkettung den Modifizierer verliert, aber der rCTE darauf besteht, dass die Typen genau übereinstimmen:
Sie haben Konto 1 als eigenes Elternteil festgelegt. Wenn Sie das übergeordnete Element dieses Kontos auf null
setzen, können Sie vermeiden, dieses Konto sowohl als Start- als auch als Endknoten zu verwenden (die Logik wird so eingerichtet, dass Sie einen Zyklus einfügen, aber diesen Zyklus nicht hinzufügen, was vernünftig erscheint ). Es sieht auch ein bisschen schöner aus, die letzte "Pfad" -Spalte in etwas wie case when parent_id is not null then path || parent_id else path end
zu ändern, um zu vermeiden, dass am Ende die Null ist.
Tags und Links sql postgresql common-table-expression recursive-query transitive-closure-table