Mit Common Table Expressions (CTE) hierarchisch und alphabetisch sortieren

Written on May 21, 2006

Thomas stand ja kürzlich vor dem Problem, eine CTE hierarchisch korrekt ausgeben zu wollen, was ihn zu Niels Berglund führte (Sorting Hierarchical CTE's).

Allerdings blieb ein Problem: Die Daten sind nun zwar hierarchisch sortiert - nicht jedoch alphabetisch innerhalb der Hierarchie.

Heute stand ich schließlich vor dem gleichen Problem - und ich glaube, ich habe eine Lösung gefunden ;-)

Ausgehend von einer Tabelle Kategorien, welche die Felder Name (nvarchar), ID (uniqueidentifier) und Parent (uniqueidentifier) besitzt, sollen also die Kategorien hierarchisch und alphabetisch dargestellt werden:

Korrekt wäre also z.B.:

Name ID Parent

Rohre und Formteile C55C8856-6205-4F76-A15A-6FCD4A68A831 00000000-0000-0000-0000-000000000000

Geschweißte Rohre und Formteile 9EEE0951-4E63-4494-BB18-88BCC1D4A3E5 C55C8856-6205-4F76-A15A-6FCD4A68A831

Rohrbögen geschweißt 8A137449-6108-47D2-8ED0-AE0EA4176EB2 9EEE0951-4E63-4494-BB18-88BCC1D4A3E5

Rohre geschweißt 085A0AA3-AB9D-4DD1-9739-77040E627445 9EEE0951-4E63-4494-BB18-88BCC1D4A3E5

Erhalten habe ich mit Niels' Lösung jedoch nur:

Name ID Parent

Rohre und Formteile C55C8856-6205-4F76-A15A-6FCD4A68A831 00000000-0000-0000-0000-000000000000

Geschweißte Rohre und Formteile 9EEE0951-4E63-4494-BB18-88BCC1D4A3E5 C55C8856-6205-4F76-A15A-6FCD4A68A831

Rohre geschweißt 085A0AA3-AB9D-4DD1-9739-77040E627445 9EEE0951-4E63-4494-BB18-88BCC1D4A3E5

Rohrbögen geschweißt 8A137449-6108-47D2-8ED0-AE0EA4176EB2 9EEE0951-4E63-4494-BB18-88BCC1D4A3E5

Nach einigem Experimentieren mit Views u.ä. bin ich auf folgende Lösung gekommen:

WITH CTE([Name], ID, ordercol, Parent)
AS
(
    SELECT [Name], ID, cast([Name] as varbinary(100)) ordercol, Parent

    FROM ProductCategory
    WHERE Parent= '{00000000-0000-0000-0000-000000000000}'
    UNION ALL

    SELECT    ProductCategory.[Name], 
        ProductCategory.ID, 
        cast(ordercol + CAST(ProductCategory.[Name] AS BINARY(4)) as varbinary(100)) ordercol, 
        ProductCategory.Parent

    FROM ProductCategory INNER JOIN

    CTE ON ProductCategory.Parent =
    CTE.ID
)

SELECT [Name], ID, Parent
FROM CTE
ORDER BY ordercol, [Name]

Damit erhielt ich o.g. gewünschtes hierarchisch und alphabetisch korrekt sortiertes Resultat. Außerdem funktioniert jetzt sogar die Änderung von ORDER BY auf [Name] DESC.