Comment puis-je obtenir les valeurs hiérarchiques de la requête ci-dessous?


8

J'ai une table nommée Categoryqui a une colonne nommée CategoryID. Il y a une colonne de référence dans la même table appelée fParentCategoryID.

J'ai besoin de séparer tous les ID de catégorie et leurs ID de sous-catégorie par une virgule. Par exemple - si l'ID de catégorie parent de 10 est 1 et si l'ID de catégorie parent de 20 est 10, alors lorsque j'imprime l'ID de catégorie 20, je dois imprimer à la fois 1 et 10 en tant que parents dans des valeurs séparées par des virgules.

J'ai essayé la requête ci-dessous mais j'obtiens NULLpour la ParChildcolonne. Veuillez aider.

;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 

utilisez ce script pour créer et remplir le tableau. (note: il y a une limite de 30K au corps de la question .. J'ai donc dû utiliser pastebin pour copier votre code et le référencer)

Réponses:


3

J'ai pu reproduire vos résultats avec vos données d'exemple.

Votre problème est que dans le cas "de base" du CTE récursif (la première instruction de sélection), vous obtenez les enregistrements où fParentCategoryID est nul et convertissez le fParentCategoryID en une colonne de caractères prête à ajouter les "enfants". Cependant, la 'chaîne' est toujours une valeur NULL à ce stade (essayez-la avec SELECT CAST (NULL AS VARCHAR (200)) ou similaire).

La deuxième instruction select tente ensuite d'ajouter d'autres valeurs de chaîne à la valeur NULL, mais par défaut, l'option de base de données "concat null renvoie des valeurs nulles" indique que si vous essayez de concaténer quoi que ce soit à une valeur NULL, vous obtenez simplement NULL - plutôt que de la traiter comme une chaîne vide.

Vous pouvez SET CONCAT_NULL_YIELDS_NULL OFF pour cette requête bien que cela soit obsolète et sera finalement supprimé dans une future version de SQL Server (vous ne devriez donc probablement pas l'ajouter au code de production!)

Un meilleur moyen est dans la première instruction select, au lieu de transtyper le fParentCategoryID en une chaîne, il suffit de transtyper le CategoryID - nous savons déjà que le parent doit être vide car ce sont les NULL.

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

Si vos données peuvent avoir un mélange de valeurs nulles et non nulles dans cette instruction select, vous pouvez également utiliser ISNULL autour d'elle pour traiter les valeurs nulles comme des chaînes vides.

Il a probablement besoin d'un nettoyage de la valeur ParChild qu'il produit lorsque vous obtenez des valeurs telles que ", 461 464", vous pouvez donc supprimer la virgule de début.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.