Wie kann ich die hierarchischen Werte aus der folgenden Abfrage erhalten?

8

Ich habe eine Tabelle Categorymit einer Spalte namens CategoryID. In derselben Tabelle befindet sich eine Referenzierungsspalte mit dem Namen fParentCategoryID.

Ich muss alle Kategorie-IDs und ihre Unterkategorie-IDs durch Kommas trennen. Zum Beispiel: Wenn die übergeordnete Kategorie-ID 10 1 ist und wenn die übergeordnete Kategorie-ID 20 10 ist, muss ich beim Drucken der Kategorie-ID 20 sowohl 1 als auch 10 als übergeordnete Elemente in durch Kommas getrennten Werten drucken.

Ich habe die folgende Abfrage versucht, aber ich bekomme NULLfür ParChildSpalte. Bitte helfen Sie.

;WITH
  cteReports 
  AS
(
SELECT c.CategoryID,
       c.fParentCategoryID,
       [level] = 1,
       ParChild=cast(CAST(c.fParentCategoryID AS VARCHAR(200)) + ',' + CAST(c.CategoryID AS VARCHAR(200)) AS VARCHAR(MAX))
FROM   retail.Category c
WHERE c.fParentCategoryID is NULL
UNION ALL
SELECT c.CategoryID,
       c.fParentCategoryID,
       [level] + 1,
       ParChild = ParChild + ',' + CAST(c.CategoryID AS VARCHAR(200))
FROM   retail.Category c
        JOIN cteReports r
            ON  c.fParentCategoryID = r.CategoryID

)

SELECT *
FROM   cteReports cr 

Verwenden Sie dieses Skript , um die Tabelle zu erstellen und zu füllen. (Hinweis: Der Fragentext ist auf 30 KB begrenzt. Ich musste also Pastebin verwenden, um Ihren Code zu kopieren und darauf zu verweisen.)

Mayooran
quelle

Antworten:

3

Ich konnte Ihre Ergebnisse mit Ihren Beispieldaten replizieren.

Ihr Problem ist, dass Sie im "Basis" -Fall des rekursiven CTE (der ersten select-Anweisung) die Datensätze erhalten, in denen fParentCategoryID null ist, und die fParentCategoryID in eine Zeichenspalte umwandeln, um die "untergeordneten Elemente" anzuhängen. Die 'Zeichenfolge' ist zu diesem Zeitpunkt jedoch immer noch ein NULL-Wert (versuchen Sie es mit SELECT CAST (NULL AS VARCHAR (200)) oder ähnlichem).

Die zweite select-Anweisung versucht dann, andere Zeichenfolgenwerte an NULL anzuhängen. Standardmäßig gibt die Datenbankoption "concat null ergibt null an" an, dass Sie immer noch nur NULL erhalten, anstatt zu behandeln, wenn Sie versuchen, etwas mit einem NULL-Wert zu verketten eine leere Zeichenfolge.

Sie könnten CONCAT_NULL_YIELDS_NULL OFF für diese Abfrage setzen, obwohl dies veraltet ist und letztendlich in einer zukünftigen Version von SQL Server entfernt wird (Sie sollten es also wahrscheinlich nicht zum Produktionscode hinzufügen!).

Ein besserer Weg ist in der ersten select-Anweisung, anstatt die fParentCategoryID in eine Zeichenfolge umzuwandeln, einfach die CategoryID umzuwandeln - wir wissen bereits, dass das übergeordnete Element leer sein sollte, da es sich um die NULL-Werte handelt.

SELECT c.CategoryID,
   c.fParentCategoryID,
   [level] = 1,
   ParChild=cast(CAST(c.CategoryID AS VARCHAR(200)) AS VARCHAR(MAX))
FROM   retail.Category c
WHERE c.fParentCategoryID is NULL

Wenn Ihre Daten in dieser select-Anweisung eine Mischung aus Null- und Nicht-Null-Werten enthalten können, können Sie auch ISNULL verwenden, um Nullen als leere Zeichenfolgen zu behandeln.

Der ParChild-Wert, den es erzeugt, muss wahrscheinlich bereinigt werden, wenn Sie Werte wie ", 461,464" erhalten, sodass Sie möglicherweise das beginnende Komma entfernen möchten.

Siebzigjähriger
quelle