Das Verarbeiten eines Baumes mit beliebiger Tiefe ist im Allgemeinen mit rekursivem prozeduralem Code verbunden, sofern Sie nicht die speziellen Funktionen einiger DBMS nutzen.
In Oracle erlaubt Ihnen die CONNECT BY-Klausel, den Baum in der ersten Reihe zu durchlaufen, wenn Sie die Adjazenzliste verwenden, wie Sie es hier getan haben.
Wenn Sie verschachtelte Sätze verwenden, erhalten Sie mit der linken Folgenummer die Anweisung, die Knoten zu besuchen.
Um mehrstufige Abfragen in einer einfachen Adjazenzliste durchzuführen, sind immer Self-Left-Joins erforderlich. Es ist einfach, eine rechtsbündige Tabelle zu erstellen:
%Vor%Um es linksbündig auszurichten, ist Ihr Beispiel etwas komplizierter. Das kommt mir in den Sinn:
%Vor%würde für n-Tier-Hierarchien funktionieren.
Sorry, Abfragen mit beliebiger Tiefe sind im Adjazenzlistenmodell nicht möglich. Wenn Sie diese Art von Abfrage häufig durchführen, sollten Sie Ihr Schema in eines der anderen Modelle von ändern Speichern hierarchischer Informationen : vollständige Adjazenzbeziehung (Speichern aller Vorfahren-Nachkommen-Beziehungen), materialisierter Pfad oder verschachtelte Mengen.
Wenn sich die Kategorien nicht viel bewegen (was normalerweise bei einem Geschäft wie Ihrem Beispiel der Fall ist), würde ich zu verschachtelten Mengen neigen.
Ich habe eine Tabelle, die hierarchische Informationen unter Verwendung des Adjazenzlistenmodells speichert. (verwendet einen selbstreferentiellen Schlüssel - Beispiel unten. Diese Tabelle kann vertraut aussehen):
%Vor%Was ist die beste Methode, um die obigen Daten in so etwas zu reduzieren?
%Vor%Jede Zeile ist ein "Pfad" durch die Hierarchie, außer dass für jeder Knoten (nicht nur für jeden Blattknoten ) eine Zeile vorhanden ist. Die Spalte category_id repräsentiert den aktuellen Knoten und die Spalten "lvl" sind seine Vorfahren. Der Wert für den aktuellen Knoten muss auch in der Spalte mit der höchsten Rechten liegen. Der Wert in der Spalte lvl1 wird immer den Stammknoten darstellen, die Werte in lvl2 werden immer direkte Nachkommen von lvl1 sein usw.
Wenn möglich, wäre die Methode zum Generieren dieser Ausgabe in SQL und würde für n-Tier-Hierarchien funktionieren.
Wie bereits erwähnt, hat SQL keine saubere Möglichkeit, Tabellen mit dynamisch variierenden Spaltenzahlen zu implementieren. Die einzigen zwei Lösungen, die ich vorher benutzt habe, sind: 1. Eine feste Anzahl von Self-Joins mit einer festen Anzahl von Spalten (AS per BobInce) 2. Generieren Sie die Ergebnisse als eine Zeichenfolge in einer einzelnen Spalte
Der zweite klingt zunächst grotesk; Speichern von IDs als String ?! Aber wenn die Ausgabe als XML oder so formatiert ist, scheint es den Leuten nicht so viel auszumachen.
Genauso wenig ist das nützlich, wenn Sie dann an den Ergebnissen in SQL teilnehmen möchten. Wenn das Ergebnis einer Anwendung bereitgestellt werden soll, kann es sehr geeignet sein. Persönlich bevorzuge ich jedoch die Abflachung in der Anwendung statt SQL
Ich bin hier auf einem 10-Zoll-Bildschirm ohne Zugriff auf SQL stecken, so kann ich den getesteten Code nicht geben, aber die grundlegende Methode wäre Rekursion in irgendeiner Weise zu verwenden;
- Eine rekursive Skalarfunktion kann dies tun
- MS SQL kann dies mit einer rekursiven WITH-Anweisung (effizienter) tun
Skalarfunktion (etwas wie):
%Vor%Ich habe seit einiger Zeit kein rekursives WITH verwendet, aber ich gebe die Syntax an, obwohl ich hier kein SQL habe, um etwas zu testen:)
Rekursiv MIT
%Vor%
BEARBEITEN - AUSGABE ist für beide gleich:
Tatsächlich kann mit dynamischem SQL innerhalb einer Speicherprozedur getan werden. Sie werden dann darauf beschränkt, was mit der gespeicherten Prozedur geschehen kann. Offensichtlich wird es zu einer Herausforderung für EXEC, die Ergebnisse in eine temporäre Tabelle zu übertragen, ohne zu wissen, wie viele Spalten zu erwarten sind. Wenn es jedoch das Ziel ist, auf eine Webseite oder eine andere Benutzeroberfläche auszugeben, lohnt sich der Aufwand ...