Ich arbeite mit einigen Tabellen, die ein Dateisystem darstellen, und ich muss den vollständigen Pfad jedes Ordners als eine abgeflachte Zeichenfolge auswählen.SQL - Nicht-Null-Adjazenzliste in Pfad konvertieren
Die erste Tabelle enthält die Details der einzelnen Ordner:
CREATE TABLE Folders(
FolderID int IDENTITY(1,1) NOT NULL,
[Name] nvarchar(255) NOT NULL)
Die zweite Tabelle enthält transitiv Schließungen von Ordner Beziehungen:
CREATE TABLE FolderClosures(
FolderClosuresID int IDENTITY(1,1) NOT NULL,
AncestorFolderID int NOT NULL, --Foreign key to Folders.FolderID
DescendantFolderID int NOT NULL --Foreign key to Folders.FolderID
IsDirect bit NOT NULL)
Für Beispieldaten, nehmen wir an, die folgenden Ordner vorhanden sind:
Documents/
Documents/Finance/
Documents/HumanResources/
Documents/HumanResources/Training/
Diese würden in diesen Tabellen wie folgt beibehalten werden :
| FolderID | Name |
+----------+----------------+
| 1 | Documents |
| 2 | Finance |
| 3 | HumanResources |
| 4 | Training |
| FolderClosureID | AncestorFolderID | DescendantFolderID | IsDirect |
+-----------------+------------------+--------------------+----------+
| 1 | 1 | 1 | 0 |
| 2 | 2 | 2 | 0 |
| 3 | 1 | 2 | 1 |
| 4 | 3 | 3 | 0 |
| 5 | 1 | 3 | 1 |
| 6 | 4 | 4 | 0 |
| 7 | 1 | 4 | 0 |
| 8 | 3 | 4 | 1 |
Einige Details zu beachten:
Jeder Ordner hat eine "Identität Reihe" in
FolderClosures
, woAncestorFolderID = DescendantFolderID AND IsDirect = 0
.Jeder Ordner, kein Ordner der obersten Ebene ist genau eine Zeile in
FolderClosures
woIsDirect = 1
FolderClosures
viele Zeilen pro Ordner enthalten kann, woAncestorFolderID <> DescendantFolderID AND IsDirect = 0
. Jedes von diesen stellt eine "Großeltern" oder entferntere Beziehung dar.Da keine Spalten nullfähig sind, geben keine Zeilen explizit an, dass ein bestimmter Ordner ein Ordner der obersten Ebene ist. Dies kann nur festgestellt werden, indem überprüft wird, dass in
FolderClosures
IsDirect = 1 AND DescendantFolderID = SomeID
keine Zeilen vorhanden sind, wobeiSomeID
die ID des betreffenden Ordners ist.
Ich möchte in der Lage sein, eine Abfrage auszuführen, die diese Daten zurückgibt:
| FolderID | Path |
+----------+------------------------------------+
| 1 | Documents/ |
| 2 | Documents/Finance/ |
| 3 | Documents/HumanResources/ |
| 4 | Documents/HumanResources/Training/ |
Ordner in beliebiger Tiefe verschachtelt werden kann, aber realistisch wahrscheinlich nur bis zu 10 Ebenen. Abfragen erfordern möglicherweise das Zurückgeben von Pfaden für einige tausend Ordner.
Ich habe eine Menge Tipps zum Erstellen dieser Art von Abfrage gefunden, wenn Daten als Adjazenzliste persistent sind, aber ich konnte keine Antwort für eine transitive Schließung Setup wie folgt finden. Die Adjazenzlisten-Lösungen, die ich gefunden habe, verlassen sich darauf, dass Zeilen mit nullbaren übergeordneten Ordner-IDs beibehalten werden, aber das funktioniert hier nicht.
Wie kann ich die gewünschte Ausgabe erhalten?
Wenn es hilft, ich bin mit SQL Server 2016.